Quick & Dirty Visual Testing 👁
Tags: testing, go, javascript, webdev
Published: 2022-04-18 20:47:23


Testing is essential, but the truth is that it is not always the case.

I have caught myself and noticed many professional friends working on freelancing projects with tight deadlines, and dealing with frameworks not easy to test (Gatsby, Next.js etc), just ignoring the testing part.

What can we do in cases like these, to ensure a good deliverable quality?
Maybe we can set up E2E tests, but then we can easily miss important visual changes. Or set up visual-testing with services like Chromatic and visit their dashboards for approvals in every deployment?

While the aforementioned options are totally valid, they can add more time in the **develop-test-deploy** loop, and time is money 💸 Those are the reason I started a project, called **Cyclopes 👁** to perform quick & dirty visual testing.

### How Cyclopes Works

Cyclopes is a minimal CLI tool to help you **capture screenshots of important pages** of your web app, and then **send them to the tools you love working** like Slack or Trello.

So basically there are two main functionalities to help you:
1. capture changes of your web app and then
2. communicate them with your client, teammates, QA engineer etc.

### How to use Cyclopes

To start using cyclopes it’s really easy. All the code below is shared in the [public repo here](https://github.com/konsalex/cyclopes-gatsby-demo) 👈

#### Install Cyclopes

Let’s install **cyclopes** with one of the following commands inside our repository. The first two will download the npm package which is very lightweight. This is because the binary of cyclopes will be downloaded in the first run if it is not found.

```sh
# npm
npm install cyclopes

# yarn
yarn add cyclopes

# golang (for Hugo folks)
go get -u github.com/konsalex/cyclopes
```

#### Setting up Cyclopes

To set up cyclopes we need to figure out some details first. Let’s create a `cyclops.yml` file in the root of our repository and paste the following content

```bash
# Directory where the images will be saved
# and/or retrieved from the channel adapters
imagesDir: "./images"

visual:
  # Path where our web-app is built
  # Useful in CI environments where we build
  # the website and the artifacts are ready
  buildDir: "./public"
  # Pages to visit and screenshot
  pages:
    # Path of the page
    - path: "/"
      # Type of device to screenshot
      device: "both"
      # Delay after the page is loaded
      delay: 2000
      screenshot: "fullpage"
    - path: "/contact"
      device: "mobile"
    - path: "team/"
      device: "desktop"
      screenshot: "viewport"
```

So what is the above configuration doing? In simple terms:
1. Save all the images to `./images`  folder
2. Find the website to serve it in the `./public` folder
3. Now for every page in `pages` iterate and screenshot

For more options, you can see the [README](https://github.com/konsalex/cyclopes#how-to-configure) in the project’s repository, and also find the default values of the options.

#### Run the CLI

Now let’s run cyclopes and check the results.

```bash
yarn cyclopes
```

If everything was successful, your `images` folder should have 4 new images (one of them attached below) 🎊 


![Example Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sxo66g8rmr1ylv71p750.jpeg)

Those are the screenshots we took of our web-app. It’s that easy!

#### Send the results to Slack (Optional)

The ultimate reason for making this CLI, was a faster feedback loop between my clients and me, especially when I was breaking stuff 🤭  That’s why a Slack adapter is included out of the box, so we can send the screenshots to our Slack workspace 

To set the Slack adapter we can extend our configuration file with the following code (assuming you have created a Slack bot):
```yaml
adapters:
  slack:
    OAUTH_TOKEN: example-token
    CHANNEL_ID: example-token
``` 

And the result should look like the image below 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/smcmxv1l65rjcavrri62.jpg)