Login and Setting Cookies for Browser Testing
00:00 So whatever you're doing, you just need to make sure that you're simulating in your test what it takes to be logged in. We already have a test for logging in as an existing user and onboarding with a link, so running those tests again before we run all the other tests that need to be authenticated would be an
00:19 enormous waste of time. And so what we're going to do is have a utility that gets us logged in. So let's go to our 2FA test right here, and we're going to need a couple of things that we'll pull in as we go. We're going to remove
00:36 this comment now, and then here we'll create a new session for the user using Prisma Session Create. So here's our session, await prisma.session, oh and let's bring in Prisma of course from our dbutils
00:52 and session.create, and here our data will include the user ID, which is the user.id that we inserted with, you know, that should be familiar, that fixture that we made earlier. And then our expiration date would be get
01:07 expiration date right here. And that gives us our session that we're going to use to be logged in, because that's the requirement, right? It's for a user to be logged in into this app, if you went through the auth workshop before, is we have the session ID in some sort of
01:26 cookie. And so speaking of the cookie, we need to get the cookie session. So let's get that cookie session from session storage, get session. We're going to await this, and the session storage is going to come from our utils. So here we get our, or create a session object, and the session object now we can say
01:46 cookie session.set, and session key will come from the auth server util, and we'll put in the session ID. And then we're going to get our set cookie header
01:59 from await session storage dot commit session cookie session. And now we've got the header for the set cookie, but this is tricky because the set cookie header that we get from this, this is the thing that is on the server that we're sending as a response. But
02:16 what we're doing is we need to set a cookie value in the browser context for our test. So we don't need a set cookie header, we need a cookie header. Not a set cookie response header, but a cookie request header. And so that's what's going to be a little tricky about this. We need to actually parse this
02:34 set cookie header so we can get the actual cookie value, as well as other configuration pieces of this as well. So we're going to use this code from Marty the Moneybag. This set cookie parser is going to come from the set cookie parser module. So import
02:53 this from this. There we go. And I think if I remember right, that is an import star as set cookie parser. There we go. So with set cookie parser, now we can parse the set cookie header.
03:10 Whoops, there we go. Set cookie header. Okay, thanks anyway Copilot, but we don't need the first item. And now I want you to be able to see what this actually looks like. And unfortunately, as of right now, eventually maybe Playwright will make this a little better. But if you add a console log here, that console log, I
03:28 have no idea where that goes. You cannot see that anywhere. And so whenever I run into that, because sometimes that does happen in testing frameworks and other tools, they'll like override console log and you're like, how do I find the thing? So here's what I do. I have what I call a throw log, where it will throw an error with a
03:46 stringified object. And so here I can pass in my cookie config. And then if I save that and we run this test, then the error message will include the stuff that I'm looking for. So it's a bit of a hack to be honest,
04:02 but it does work and it works well. So I'm happy with that. So here we have our cookie config. The name is en-session. The value is this string. Like all of that stuff that you would expect. We've got the path, all of that stuff. And so that's pretty cool actually. So we can use that as part of this next part to actually create
04:22 the cookie that goes into the page context. So let's do that now. Await page.context. And we need to call that as a function and then add cookies. And this takes an array of cookie config objects. So we'll just spread that cookie config. There you go.
04:41 But it does require a domain and local host is satisfactory for us. So let's see what this is complaining about. So this is complaining because the cookie config doesn't necessarily have the type that we're looking for in add cookies.
04:58 We're going to add an as any and I welcome you to find a nicer way to to do that. Maybe you can parse it with Zot or something. It does work. So we're going to just add the as any and pretend that we don't we're not doing that. Okay so with that now
05:14 we should be able to do the first part of this two-factor auth test that gets us to the two-factor auth enable page. So if I hit play and we'll scooch this over while we wait. There we go. And it totally worked. So we land on the settings profile page as a new
05:30 logged in user and because our fixture is set up the way that it is this insert user that user is created and then deleted by the end of the test which is pretty sick. And we are able to be authenticated as that user during the course of the test. So we
05:46 don't have to do any like run this test first and and then run this one like we want to maintain that isolation. But yeah it works out really well. So that is how you get this first bit of this two-factor auth test working. So we'll just review
06:04 really quick. The whole objective here is to just simulate in the browser what your actual app does when you log in. And so what we do is we create a session and then we get the cookie session from our session storage. We set that
06:24 value and then we get what the set cookie header would be if our server were to do all this. Now again like our actual server is running in a different process. Playwright's running in this process but all this stuff works because it's using the same exact code which is pretty cool. And if that code is broken this
06:41 definitely won't work. Even if it's broken in the same way both in our server and in our application or our tests yeah that's not going to work. So we're pretty confident that this works and in addition we already have a login as an existing user test anyway. So if that is broken then we know
07:00 that our login needs to be fixed. Okay so and so that's why we're safe to use our application code in our test because we are covering that code in our tests as well. Okay so we get that cookie header we parse it out and to get that cookie configuration and then we add a cookie to the page context
07:18 and then from there once we go here it'll start sending that cookie along and we are golden. So good job!