E2E Testing Login Flow
In this lesson, we will learn how to test the login flow with Playwright.
As you can see, how much logic is involved in the login flow (similarly in flows like register, payments, etc.,). We have to check if the user is already logged in, if not then we have to click on the login button, then we have to enter the email and password, and then click on the login button. These are a lot of steps to test manually. Also, imagine bigger flows of the application, it will be tiring to test them manually with every change in the code.
This is where E2E testing comes into play.
Playwright
There are a lot of E2E testing tools available in the market like Selenium, Cypress, Puppeteer, etc. But in this course, we will be using Playwright.
Let us install Playwright in our project.
Run the install command and select the following to get started:
- Name of your Tests folder:
e2e
(default would betests
, we are changing it toe2e
) - Add a GitHub Actions workflow to easily run tests on CI:
false
(default is false) - Install Playwright browsers:
true
(default is true)
This will install Playwright in your project, create an e2e
folder with a sample test, a tests-example
folder, and a playwright.config.ts
file.
We can delete the tests-example
folder as we will not be using it. Also, we can delete the sample test file in the e2e
folder.
Login Flow Test
Now, what are we supposed to test in the login flow? The better question is, how does the user login? Let's break it down:
- The user either goes to the login page directly or clicks on the login button from the home page.
- The user enters the email and password.
- The user clicks on the login button.
- The user should be redirected to the dashboard page.
Also, we have to test the error scenarios like:
- The user uses invalid credentials.
- The user lands on the dashboard page directly without logging in.
Tests
Let us write the tests to cover the above scenarios. Create a new file login.spec.ts
in the e2e
folder.
We would need the test
and expect
functions from Playwright to write and assert the tests. We are using the test.describe
function to group the tests related to the login flow.
Test 1: User goes to the login page from the home page
In this test, we:
-
Navigate to the home page.
- We are using the
page.goto
function to navigate to the home page.
- We are using the
-
Click on the login link.
- We are using the
page.getByRole
function to get the login link and then click on it.
- We are using the
-
Assert that the URL should be
http://localhost:3000/login
.- We are using the
expect(page).toHaveURL
function to assert that the URL should behttp://localhost:3000/login
.
- We are using the
See how the test is async
and we are using await
for the Playwright functions. This is because Playwright functions return promises.
Auto-wait. Playwright waits for elements to be actionable prior to performing actions. It also has a rich set of introspection events. The combination of the two eliminates the need for artificial timeouts - the primary cause of flaky tests.
How to run the test?
To run the test, run the following command in a new terminal:
Remember to start the development server before running the tests. If you want
to do this automatically, you can configure it in the playwright.config.ts
file. At the end of the file, you should see a couple of commented lines that
you can uncomment to start the server before running the tests.
This will run the tests in the e2e
folder as defined in the playwright.config.ts
file and generate an HTML report at the end.
You can also run the tests more interactively through the UI by using the following command:
This will open a UI where you can run the tests, see the logs, and debug the tests.
Should we also test if the user can go to the login page directly?
Maybe we can add that explicit test. But we will anyway cover that in the next test where the user logs in successfully.
Test 2: User logs in successfully and is redirected to the dashboard page
In this test, we:
-
Navigate to the login page.
- Here, we are navigating to the login page directly.
-
Fill the email and password.
- We are using the
page.getByLabel
function to get the email and password fields and then fill them with the test data.
- We are using the
-
Click on the login button.
- We are using the
page.getByRole
function to get the login button and then click on it.
- We are using the
-
Assert that the URL should be
http://localhost:3000/dashboard
.- We check if the user is redirected to the dashboard page after logging in.
Run the tests again to see if the user can log in successfully and is redirected to the dashboard page.
Test 3: User logs in with invalid credentials
In this test, we:
-
Navigate to the login page.
- We are navigating to the login page directly.
-
Fill the email and password.
- We use the same test data for the email but an invalid password.
-
Click on the login button.
-
Assert that the error message should be shown.
- We are using the
page.getByText
function to get the error message and then assert that it should be visible. - Our error message is
Invalid login credentials
provided by Supabase when the user logs in with invalid credentials. - We are using the
first
function to get the first occurrence of the error message. This is because two error messages on the page repeat, one for the email and one for the password. We are only interested in the first one in this case.
- We are using the
Run the tests again to see if the error message is shown when the user logs in with invalid credentials.
Test 4: The user if not authenticated, should be redirected to the login page
In this test, we:
-
Navigate to the dashboard page directly.
- We are navigating to the dashboard page directly.
-
Assert that the URL should be
http://localhost:3000/login
.- We are asserting that the user should be redirected to the login page if they are not authenticated.
We can, of course, make this test and feature more robust by also redirecting them back to the original page after they log in. But for this course, we are just checking if the user is redirected to the login page.
Though we wrote the code for the tests, Playwright has a nice test generator that can generate the code for you. You can use it to generate the code and then modify it as per your requirements. It is quite helpful when you are not sure how to write the code for a particular test.
That is it for this chapter, we will next work on the register page.
At this point, our code should match the code in the branch 4-e2e-login-flow
.