Monitoring your Website End to End with Playwright
Tags: playwright, monitoring, javascript
Published: 2024-03-15 12:30:41

It is hugely important to your business that the login, signup and payment flows of your website are working as expected. If any of these are broken, it can have a huge impact on your business. You could lose customers, revenue, and reputation. That's why it's important to continuously monitor these flows to make sure they are working as expected. And it's not enough to test the functionalities when you deploy a new version of your website. You need to monitor them all the time to guard against operational problems. Especially today, when systems are made up of a 
multitude of services, PaaS and SaaS offerings. End-to-end monitoring checks can serve as smoke tests that detect when any required systems is having problems that break the end to end flow.

In this article, we'll show you how to monitor the login to your website end to end with [Playwright](https://playwright.dev/), Javascript and [Checkson](https://checkson.io).

### What is Playwright?

[Playwright](https://playwright.dev/) is a Node.js library for automating browsers. It allows you to write scripts to interact with web pages, just like a real user would. You can use it to fill out forms, click buttons, and navigate between pages. It is most commonly used for end-to-end testing of the code-base, but it's also a great tool for monitoring continuously.

There are similar tools like Puppeteer, Selenium, and Cypress, but Playwright is probably the most popular one at the moment.

### Monitoring the Login Flow

Let's use a [dummy signin flow](https://practicetestautomation.com/practice-test-login/) as an example.

First, we need to install Playwright and a browser for Playwright to use. We can do this with the following commands:

```bash
mkdir playwright-check
cd playwright-check
npm install playwright
npx playwright install chromium
```

Then, we can write a script called `index.js` to automate the login:

```javascript
const {chromium} = require('playwright');
const {expect} = require('playwright/test');

(async () => {
  const browser = await chromium.launch();

  const page = await browser.newPage();

  try {

    await page.setViewportSize({ width: 1280, height: 1200 });

    await page.goto('https://practicetestautomation.com/practice-test-login/');
    await page.getByLabel('Username').fill('student');
    await page.getByLabel('Password').fill('Password123');
    await page.click('#submit.btn');

    await expect(page.getByRole('heading')).toContainText('Logged In Successfully');

    console.log("Logged In Successfully")
  } catch (error) {
    console.log(error);
  } finally {
    await browser.close();
  }
})();
```

This opens up the login website and fills out the username and password fields. It fills the username and password fields by finding their label. 

It then selects the submit button (using the [CSS selector](https://playwright.dev/docs/other-locators#css-locator) `#submit.btn`) and clicks it.

Then, it is evaluated if text appears that confirms that the login was successful.

You can run this script with Node JS:

```bash
node .
```

You should see the message "Logged In Successfully" in the console.

### Creating a Screenshot

It would be useful to generate a screenshot, if there was an error to help with analysis of the error. We can do this by adding the following line to the catch block:

```javascript
await page.screenshot({ path: './error-screenshot.jpg' });
```

In case of an error, a screenshot will automatically be created and stored as a file.

We now want to run this regularly on [checkson.io](https://checkson.io). For this we have to created a Docker image out of our script. This is pretty easy since there are base images available for Playwright that we can use.

Let's create the following `Dockerfile`:

```Dockerfile
FROM mcr.microsoft.com/playwright:v1.42.1-jammy

WORKDIR /usr/src/app
COPY package*.json /usr/src/app
RUN npm clean-install

COPY index.js /usr/src/app

CMD [ "node", "index.js" ]
```

This uses a base image, copies our `index.js`, `package-lock.json` and `package.json` to the image and runs `npm clean-install`. It executes the script as the `CMD` of the Docker image.

We can build the Docker image:

```bash
docker build -t myuser/end-to-end-playwright-check .
```

You can run the Docker image with the following command:

```bash
docker run --rm -it myuser/end-to-end-playwright-check
```

Note: It could happen that you see an error message like this: 

```
browserType.launch: Executable doesn't exist at /ms-playwright/chromium-1105/chrome-linux/chrome
╔══════════════════════════════════════════════════════════════════════╗
║ Looks like Playwright Test or Playwright was just updated to 1.42.1. ║
║ Please update docker image as well.                                  ║
║ -  current: mcr.microsoft.com/playwright:v1.40.0-jammy               ║
║ - required: mcr.microsoft.com/playwright:v1.42.1-jammy               ║
║                                                                      ║
║ <3 Playwright Team                                                   ║
╚══════════════════════════════════════════════════════════════════════╝
```

In that case, please update the line starting with `FROM` in the Dockerfile to the version indicated in the error message. 

When running the Docker image, you should also see the output: "Logged In Successfully".

### Creating a Checkson Attachment

We want to make the screenshot available on checkson.io. For this, we have to provide it as a so  called attachment. Attachments are arbitrary files that can be added to a run of a Checkson check. More information can be found in the [docs](https://docs.checkson.io/attachments/).

Creating an attachment is easy: They only have to be written to a special directory: `$CHECKSON_DIR/attachments`. All files from that directory will be picked up by the Checkson cloud runner when it executes the check.

Let's extend our Playwright check so that the screenshot is provided as an attachment.

```javascript
const {chromium} = require('playwright');
const {expect} = require('playwright/test');
const {existsSync, mkdirSync} = require('fs');

const { CHECKSON_DIR } = process.env;

(async () => {
  const browser = await chromium.launch();

  // Make sure that the attachments directory exists
  const attachmentsDir = `${CHECKSON_DIR}/attachments`;
  if (!existsSync(attachmentsDir)){
   mkdirSync(attachmentsDir);
  }
  const screenshotFilePath = `${attachmentsDir}/screenshot.jpg`;

  const page = await browser.newPage();

  try {

    await page.setViewportSize({ width: 1280, height: 1200 });

    await page.goto('https://practicetestautomation.com/practice-test-login/');
    await page.getByLabel('Username').fill('student');
    await page.getByLabel('Password').fill('Password123');
    await page.click('#submit.btn');

    await expect(page.getByRole('heading')).toContainText('Logged In Successfully');

    console.log("Logged In Successfully")
  } catch (error) {
    console.log(error);
    await page.screenshot({ path: screenshotFilePath });
  } finally {
    await browser.close();
  }
})();
```

### Deploying the Check to checkson.io

Now, everything is ready for the check to be deployed to Checkson and to configure notifications. It only takes 5 minutes. Here is a [guide on how to to it using the CLI](https://docs.checkson.io/quickstart/#configuring-the-check-with-the-cli) and here is a [guide on how to do it via the web UI](https://docs.checkson.io/quickstart/#configuring-the-check-with-the-web-app).

After you have done this, you will receive an E-Mail or Slack message once the login to your website fails for any reason.