Well, if you only run the migrations there won't be any data. You need to use a seeder class or the factory to create a new user that you can use to login with. So DatabaseMigrations is correct for your tests, but you also need to add data so you can work with it
SImple Dusk test from manual fails
I'm trying to follow the instructions here:
https://laravel.com/docs/7.x/dusk#creating-browsers
But the assertPathIs test keeps failing. The generated screenshot shows a "credentials do not match our records".
I should mention that I also tried setting the password for the user when its created by the factory (bcrypted, of course).
I have a .env.dusk.local configuaration file with the correct APP_URL (as the error screenshot is produced). In this file I also have the dust testing database settings which is empty.
Am I right to assume that using DatabaseMigrations is enough to create all the tables in the database when dusk runs?
If so, why is this very simple test not working? If not, what exactly do I need to do to get it to work? Thanks
Consider showing the test that fails
@bobbybouwmann: I add data before running the actual test using a factory
@Sinnbeck: Ok, here is the dusk test:
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use Illuminate\Support\Facades\Hash;
use App\User;
class UserTest extends DuskTestCase
{
use DatabaseMigrations;
/** @test */
public function a_user_logs_in_successfully()
{
$user = factory('App\User')->create([
'email' => '[email protected]',
'password' => Hash::make('leomessi')
]);
$this->browse(function (Browser $browser) {
$browser->visit('/login')
->type('email', '[email protected]')
->type('password', 'leomessi')
->press('Login')
->assertPathIs('/home');
});
}
}
Also, here my User factory:
$factory->define(User::class, function (Faker $faker, $attrib) {
return [
'name' => (array_key_exists('name', $attrib)) ? $attrib['name'] : $faker->name,
'email' => (array_key_exists('email', $attrib)) ? $attrib['email'] : $faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => $attrib['password'],
'remember_token' => Str::random(10),
];
});
Can you show the blade form you are trying to login using? :)
@sinnbeck: It's Laravel's standard Auth login template:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Login') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('login') }}">
@csrf
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<div class="col-md-6 offset-md-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
<label class="form-check-label" for="remember">
{{ __('Remember Me') }}
</label>
</div>
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Login') }}
</button>
@if (Route::has('password.request'))
<a class="btn btn-link" href="{{ route('password.request') }}">
{{ __('Forgot Your Password?') }}
</a>
@endif
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Did you change anything in the login flow? Did you add a boot method to your User model, which might hash the password twice?
I don't see anything strange here. Have you tried doing a dd(User::all()) before the browser call to see if you get any data back from the database? Maybe the configuration is incorrect?
No I didn't add a boot method,
and yes, I did dd(User:all()), and it all seems okay to me. Here is the output, please see if you can spot anything wrong in there:
Illuminate\Database\Eloquent\Collection\^\ {#2207
#items: array:1 [
0 => App\User\^\ {#2115
#fillable: array:3 [
0 => "name"
1 => "email"
2 => "password"
]
#hidden: array:2 [
0 => "password"
1 => "remember_token"
]
#casts: array:1 [
"email_verified_at" => "datetime"
]
#connection: "mysql"
#table: "users"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:8 [
"id" => 1
"name" => "Bart Lesch"
"email" => "[email protected]"
"email_verified_at" => "2020-08-10 04:02:21"
"password" => "yLARACASTS_SNIPPET_PLACEHOLDERQOf/UTz7CmzLXq4gcjZWu9Ve8cyft0EL5I02YRvvztKLXXtAskX2"
"remember_token" => "hb6yQ2SsRn"
"created_at" => "2020-08-10 04:02:21"
"updated_at" => "2020-08-10 04:02:21"
]
#original: array:8 [
"id" => 1
"name" => "Bart Lesch"
"email" => "[email protected]"
"email_verified_at" => "2020-08-10 04:02:21"
"password" => "yLARACASTS_SNIPPET_PLACEHOLDERQOf/UTz7CmzLXq4gcjZWu9Ve8cyft0EL5I02YRvvztKLXXtAskX2"
"remember_token" => "hb6yQ2SsRn"
"created_at" => "2020-08-10 04:02:21"
"updated_at" => "2020-08-10 04:02:21"
]
#changes: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#visible: []
#guarded: array:1 [
0 => "*"
]
#rememberTokenName: "remember_token"
}
]
}
This does look correct to me. I don't see any reason why this wouldn't work? The only last thing I can think of is that you're connecting the wrong URL or that your local environment is displaying the incorrect login form somehow.
Does the screenshot of the failed test show the correct website for you?
Left this for a while but had to get to the bottom of it now. Turns out the hashing of the password in the factory wasn't needed. Seems like Laravel takes care of it automatically behind the scene. So the double hashing is what broke the code
Please or to participate in this conversation.