• Blog
  • Documentation
  • Courses
  • Changelog
  • AI Starters
  • UI Kit
  • FAQ
  • Supamode
    New
  • Pricing

Launch your next SaaS in record time with Makerkit, a React SaaS Boilerplate for Next.js and Supabase.

Makerkit is a product of Makerkit Pte Ltd (registered in the Republic of Singapore)Company Registration No: 202407149CFor support or inquiries, please contact us

About
  • FAQ
  • Contact
  • Verify your Discord
  • Consultation
  • Open Source
  • Become an Affiliate
Product
  • Documentation
  • Blog
  • Changelog
  • UI Blocks
  • Figma UI Kit
  • AI SaaS Starters
License
  • Activate License
  • Upgrade License
  • Invite Member
Legal
  • Terms of License

Programmatic Authentication with Supabase and Cypress

Dec 18, 2022

Testing code that requires users to be signed in can be tricky. In this post, we show you how to sign in programmatically with Supabase Authentication to improve the speed of your Cypress tests and increase their reliability.

supabase
testing
cypress
auth

While Cypress has greatly simplified E2E testing for developers, it can still be tricky at times. For example, a best practice while running E2E testing is bypassing the UI when testing pages behind user authentication.

The Cypress team, in particular, has long advocated for programmatically authenticating users when testing code not related to the authentication flow.

For example, if you are testing your Dashboard code, there is no need to use the UI to authenticate your users: this will only result in slower, heavier and more flaky E2E tests.

In this post, we show you how to sign in programmatically with Supabase Authentication to improve the speed of your Cypress tests and increase their reliability.

Adding a Cypress command to sign-in programmatically

Cypress allows us to write global commands that we can access using the cy variable, which is globally available in all our Cypress tests.

To do so, we will extend Cypress commands with a new command we will name signIn, and will be available to us using cy.signIn(). Neat, isn't it?

First of all, we want to play nice with Typescript. That means we extend the Typescript's interface in a filename we name global.d.ts:

global.d.ts
namespace Cypress {
interface Chainable {
signIn(
redirectPath?: string,
credentials?: { email: string; password: string }
): void;
}
}
}

Now, we can extend Cypress with a custom command named signIn. To do so, we add a command using the method Cypress.Commands.add:

tsx
Cypress.Commands.add(
'signIn',
(
redirectPath = '/',
credentials = {
email: Cypress.env(`EMAIL`) as string,
password: Cypress.env(`PASSWORD`) as string,
}
) => {
// body
}
);

The above function takes two parameters:

  1. A path where to redirect users after signing in
  2. The user credentials, but by providing some default values using environment variables

Let's now write the body of the function:

tsx
// the function we will define to sign users in
signInProgrammatically(credentials); // <--- implementation is below
// after sign-in, we redirect the users to the provided path
cy.visit(redirectPath);

Signing in using Cypress sessions

If you are using Cypress 12, you will need to use cy.session. The cy.session command will preserve the session cookie between tests, otherwise, the user will get logged out.

tsx
Cypress.Commands.add(
'signIn',
(
redirectPath = '/',
credentials = {
email: Cypress.env(`EMAIL`) as string,
password: Cypress.env(`PASSWORD`) as string,
}
) => {
cy.session([credentials.email, credentials.password],
() => {
cy.log(`Signing in with ${credentials.email}`);
signInProgrammatically(credentials);
}
);
cy.visit(redirectPath);
}
);

Using the Supabase SDK to authenticate users in Cypress E2E tests

To sign our testing users in without having to interact with the application's UI, we will use the Supabase client SDK.

First, we initialize the Supabase client using the SUPABASE_URL and SUPABASE_ANON_KEY environment variables:

tsx
function getClient() {
const url = Cypress.env(`SUPABASE_URL`);
const key = Cypress.env(`SUPABASE_ANON_KEY`);
invariant(url, `Missing SUPABASE_URL env variable`);
invariant(key, `Missing SUPABASE_ANON_KEY env variable`);
return createBrowserClient(url, key);
}

Signing users in

Now that we can create an instance of the Supabase SDK, we can use it to sign users in programmatically:

tsx
function signInProgrammatically(credentials: {
email: string;
password: string;
}) {
const { email, password } = credentials;
return getClient()
.auth.signInWithPassword({
email,
password,
})
.then((response) => {
if (response.error) {
return Promise.reject(response.error.message);
}
})
.catch((e) => {
console.error(e);
return Promise.reject(e);
});
}

Finally, the signInProgrammatically function completes the cy.signIn() command defined in the beginning.

Writing a Test that signs users in programmatically

Whenever you write tests that require users to be signed in, you can write the below:

tsx
describe(`Create Invite`, () => {
const email = `invited-member@makerkit.dev`;
before(() => {
cy.signIn(`/settings/organization/members`);
});
// your tests go here
});

As you can see, we can pass any path to the signIn function: after signing in, we redirect the users directly to that page, rather than having to use the UI.

By programmatically signing users in, we will dramatically improve your E2E tests' speed and make them more reliable. Regardless, no need to test the authentication page over and over!

Some other posts you might like...
Jun 9, 2025Claude Code: Build a SaaS with AIThis is a step-by-step guide to building an AI Content Repurposer SaaS by vibe-coding with Claude Code and Makerkit.
Apr 24, 2025The Ultimate Guide to Secure API Key Management in Supabase ProjectsLearn how to build a secure, production-grade API key system in Supabase with PostgreSQL roles, Row Level Security, and scope-based permissions. Complete with code examples.
Jan 17, 2025Best Practices for Building a SaaS with Windsurf and MakerkitWindsurf is a new AI-powered editor taking the developer experience to the next level. With the new optimized rules for Makerkit, building a SaaS just got a lot easier!
Jan 16, 2025Best Practices for Building a SaaS with Cursor and MakerkitCursor is the hottest AI editor in the market. With the new optimized rules for Makerkit, building a SaaS just got a lot easier!