-
-
Notifications
You must be signed in to change notification settings - Fork 192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use better technique to determine whether user is logged in #131
Conversation
…ogout link on the front page.
…ogout link on the front page.
// Look for the logged-in class on the body tag. | ||
// This should work with almost any theme. | ||
$body = $page->find('css', 'body'); | ||
if ($body->hasClass('logged-in')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should make the logged-in
class configurable, the same way the log out text is (see getDrupalText()
usage below for example). (Same goes for the below form#user-login
.)
I like this direction. This is a very-often-requested feature! |
Here we go. The two checks can now be altered in the selector section of the yml file. Please have a look :) |
I'd like to help on this. How can I run the travis-build locally (ubuntu linux) to debug the problem ? |
I've never had much luck getting travis to run locally (there are various online blogs about it, but they get deprecated every 6 months or so). However, you should be able to get the tests up and running locally by duplicating what is done in the Essentially:
|
Yes you are right. Hope I get the same problems like Travis does ;). Will try to accomplish that. |
…ed any page yet. Also removes the unnecessary variable.
I just wrapped the first check for the css class in a try {} statement. When using the Drupal api driver, there was no page loaded at this point and this caused the login process to break. |
I found no other way to check if the driver already loaded a page. Does anyone have a better approach? |
So we still need a logout-link or css to determine if there is a user logged in ? |
if ($page->has('css', $this->getDrupalSelector('logged_in_selector'))) { | ||
return TRUE; | ||
} | ||
} catch (\Behat\Mink\Exception\DriverException $e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use a use
statement instead of having the full namespace here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course we can :)
Pretty sure you'd want to look up the session ID and then check to see if there's a cookie named that, e.g.
Rather than testing for something that may or may not be on the page. I'm pretty sure that |
That makes a ton of sense. Thanks @MKorostoff 👍 |
If anyone runs into this issue and needs a work around before a fix is committed, then the following assertions can be created in your FeatureContext that implement a customized loggedIn() check that can be changed as needed for your site. The assertion code is a direct copy and paste from DrupalContext, and the text has the same beginning with an addition of " on this site". class FeatureContext extends RawDrupalContext implements SnippetAcceptingContext {
/**
* Check logged in status.
*
* Overrides RawDrupalContext::loggedIn().
* @see https://github.com/jhedstrom/drupalextension/pull/131.
*/
public function loggedIn() {
$session = $this->getSession();
$page = $session->getPage();
// Body class check from pull/131.
$body = $page->find('css', 'body');
return $body->hasClass('logged-in');
}
/**
* RawDrupalContext::assertAnonymousUser() with better logged in check.
*
* @Given I am an anonymous user on this site
* @Given I am not logged in on this site
*/
public function assertAnonymousUserOnThisSite() {
// Verify the user is logged out.
if ($this->loggedIn()) {
$this->logout();
}
}
/**
* Creates and authenticates a user with the given role(s).
*
* RawDrupalContext::assertAuthenticatedByRole() with better logged in check.
*
* @Given I am logged in as a user with the :role role(s) on this site
*/
public function assertAuthenticatedByRoleOnThisSite($role) {
// Check if a user with this role is already logged in.
if (!$this->loggedInWithRole($role)) {
// Create user (and project)
$user = (object) array(
'name' => $this->getRandom()->name(8),
'pass' => $this->getRandom()->name(16),
'role' => $role,
);
$user->mail = "{$user->name}@example.com";
$this->userCreate($user);
$roles = explode(',', $role);
$roles = array_map('trim', $roles);
foreach ($roles as $role) {
if (!in_array(strtolower($role), array('authenticated', 'authenticated user'))) {
// Only add roles other than 'authenticated user'.
$this->getDriver()->userAddRole($user, $role);
}
}
// Login.
$this->login();
}
}
} |
Just checked it out, it looks like the session cookie is only set if you are logged in. For some reason, I had in mind that this cookie is even set when you are logged out. I try to update this pull request asap :) |
Setting this as a target for version |
I am experiencing an issue that may be related to this one: I'm creating a custom step where I need the UID of the current user to check certain permissions, but it always returns as 0 (anonymous) even though my test generates a user with a particular role. However I'm using a background to generate the user for multiple scenarios.
@recrit My test.feature looks something like this:
The test fails during the background stage. I'm wondering if that error is being triggered in the loggedIn() function where $session->getPage(); is called. My workaround for the time being is to run these tests against user that currently exist in the database although it's not ideal for repeat-ability. I'm very new at behat/drupal testing so I very well may have missed something obvious, I'd appreciate any pointers on what to look for. |
It turns out my problem was solved after getting some tips on this thread: #173. |
I just ran into this with Drupal 8 and minimal profile, which does not have a logout link. Interestingly it just started failing when using some Drupal Context tests. I am not sure if it is possible or wanted to distinguish versions, but on Drupal 8 a logged in user can be easily identified by: drupalSettings.user.uid being set to the user id of the user. |
Agreed. Let's pursue this in #237. |
Use better technique to determine whether user is logged in #131
Not all websites have the logout link on the front page, in my case, Chrome with Selenium was simply to fast, admin-menu showed up after the check for the link happened.
Since there is no real 100% reliable method in D7, I've implemented two more methods to determine if a user is logged in. (D8 has the user information in the global Drupal Javascript object)
First test: Check for a "logged-in" class on the body element, most themes support this. (Mothership for example doesn't)
Second test: Visit "/user/login", if there is no login form, the user should be logged in.
I also had the Idea to simple check "/user/login" for a 403 status code, but this is not supported by Selenium because it is out of scope. (https://code.google.com/p/selenium/issues/detail?id=141)