Hello everyone! Reading emails in automated tests is a trick that you might need to know how to do in a lot of the projects. Here’s why and how to deal with it… Why Is This Important? Well, if the system sends emails - you might want to verify that they are being sent and the content is right, including clickable links. So these are the usual scenarios when you need this: Sign up. A lot of platforms send a confirmation email once you create an account, and you need to click a confirmation link from the email. Invoices. If your app does any payments - they usually send a cheque or invoice via email, so you might want to see if their contents are correct too. Results. Like medical test results. In my experience - some hospitals send an email with test results once they are done (or at least a link to a personal page where you can view the report). … Of course, this is not the complete list - these are just the use cases I’ve met the most in my career. Failing to verify these scenarios might lead to users not getting emails or getting the wrong information in emails. In one of the projects, it helped us find early an expired token. SendGrind What Are the Complications of Reading Emails in Tests? Reading emails is a tricky thing to do, but not an impossible one. Early email clients were using to fetch emails from the server, but there’s a small problem - it deletes the emails from the server once they are downloaded. POP3 Later, protocol came in - it allows you to simply read emails from the server. IMAP The problem is - or when you connect for the first time (like when you restart an automated test). some services ban these protocols make you confirm your identity On the other hand, some services like provide a to manipulate your emails, but there’s another problem - the documentation and its libraries are not really that user-friendly (especially for those who don’t work with email testing much). Gmail REST API This is where comes in - an library that allows you to read emails and even open them in your browser if you use browser automation tools like . gmail-getter npm Playwright Reading Gmail Emails With Gmail-Getter First thing first - you need to install the package in your project: npm install gmail-getter Create a Google Cloud Console Project, and Obtain Credentials To log into you need to obtain credentials: a , a , and a . These credentials let you get an Access token, which is required in further requests (like getting a list of emails or a single email, etc.). Gmail API, Client ID Client Secret Refresh token Steps to go: Create a project in . Google Cloud Console Create in the section ( ) and download it. OAuth credentials API & Services preferably, select app there if you need it for automated tests Desktop Enable the . Gmail API Obtain a Refresh token. To get a Refresh token - simply execute a command in a project root: npx gmail-getter get-refresh-token (or anywhere else if you've got the package installed globally) get-refresh-token You must put the file in a place where you will execute the command. credentials.json ⚠️ credentials file name is case-sensitive ⚠️ Obtain Access Token Once the configuration is done, you must get an Access token in your automated tests. I’d say that the best place for it is a global setup (a function that executes before the test run starts). So, it’ll be something like this: import {getToken} from 'gmail-getter' export default async function globalSetup() { process.env['ACCESS_TOKEN'] = await getToken( process.env.CLIENT_ID!, process.env.CLIENT_SECRET!, process.env.REFRESH_TOKEN! ) } The example above uses environment variables, for which you will definitely need to install the package as well. dotenv But, if you wanna keep things simple - you can use this snippet wherever you need the token to be accessible from: const accessToken = await getToken( '<put-your-client-id-here>', '<put-your-client-secret-here>', '<put-your-refresh-token-here>' ) Get Emails Right now, uses to find the email you need: Gmail’s REST API its own query language const email = await checkInbox(accessToken!, 15000, 1500, 'from:squier7 subject:Test!') The command above returns you an email object, but you still need to get either its contents or a link. Replace to your own query following the syntax from the link above ☝️ from:squier7 subject:Test! You can parse a link using : a regex const link = parseLinkFromHtml(email!, /(https:\/\/)(\S*)(gmail-getter)([\w\/\?\=\-]*)/im) Replace with your own regular expression ☝️ /(https:\/\/)(\S*)(gmail-getter)([\w\/\?\=\-]*)/im OR get the whole HTML content of the email, and render it in your browser: import {getToken, parseHtml} from 'gmail-getter' import {test} from '@playwright/test' test('Render an email', async ({page}) => { const accessToken = await getToken( '<put-your-client-id-here>', '<put-your-client-secret-here>', '<put-your-refresh-token-here>' ) const email = await checkInbox(accessToken!, 15000, 1500, 'from:squier7 subject:Test!') // get an email const html = parseHtml(email!) // parse HTML from the email await page.setContent(html) // render the email in the browser }) Overall I think it’s pretty obvious now that working with emails in automated tests might be tricky! But knowing these tricks makes things much easier. You might still go through some other email services or try , but I guarantee you - it won’t be as easy as it is in this guide, as you’d need to create a helper of your own, like provided here. IMAP gmail-getter You can find the on . too. Playwright example GitHub Cypress example