Screenshots: a perfect task to automate!
Tags: camunda, automation, websiteshot, screenshots
Published: 2021-02-14 06:42:57

Do you also have to create or update screenshots of web products all the time? Or at least over and over again and then you think: oh man, does this have to be again? Welcome to the club! It takes me about 40 seconds per screenshot, so that's almost 7 minutes for 10 screenshots alone, just looking at the pure creation. So five iterations means over 30 minutes. What if I told you that you could automate and standardize the whole process in 30 minutes with Camunda Cloud and Websiteshot?

Maybe it's not immediately obvious why you would need such a process. But there are some use cases that lend themselves to it:

- Documentation: Screenshots are a visual extension of documentations that support or clarify a technical description. Especially in the environment of SaaS products, which have different views, screenshots are very helpful.
- Evolution of products: If you wonder what your product looked like 6 months or 2 years ago, you probably wish you had taken screenshots from that time.
- Visual fast-check after a release: Maybe you want to take a quick look at some (or all) views after a release. For this you can also use screenshots that give a snapshot of the latest views.

Here's the scenario I'd like to walk you through in this tutorial:

- A Camunda Cloud process orchestrates the screenshot generation.
- We use Websiteshot to generate the screenshots. We use this SaaS because it's quite easy to configure your URLs and the API is quite easy to use.
- Finally, the finished screenshots are uploaded to an S3 bucket. Of course this can be exchanged with any other destination (Google Cloud Bucket, FTP server, Dropbox).

So for this tutorial, you'll need an account for [Websiteshot](https://websiteshot.app) and [AWS](https://aws.amazon.com/). The free tier offerings are perfectly sufficient for what we have in mind :)

## First iteration

Let's start with the first iteration. This is the most minimal process that meets our requirements.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xu5febusd7j1r0dqfq3t.jpg)

As you can see, the process consists of three very simple steps that correspond to the scenario described above:

1. Trigger screenshot job
2. Wait 60 seconds for the screenshots to be generated (Websiteshot doesn't offer webhooks yet, but it's on the roadmap)
3. Upload screenshots

Step 1 and 3 are service tasks, for each of which we again implement a simple worker. The second step is a timer event.

## Let's build the workers

We need workers that interact with two services. What simplifies things enormously: both Websiteshot and AWS offer NodeJS SDKs that make integration very easy.

### Create screenshots

The worker is quite simple, as the actual screenshot configuration takes place within Websiteshot. Templates can be created there, which contain the parameterization and all URLs.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/e6imb38hhnl7rzja27ad.png)

So that the service task can be used quite flexibly, we pass the `TemplateId` to be used as a service task header. With this approach we don't have to touch the worker if we want to use different templates.

{% gist https://gist.github.com/urbanisierung/dc48a110f446f4e91479d473cac823a0 %}

Websiteshot integration is not worth mentioning with the Library:

```js
const response: CreateResponse = await this.websiteshotController.create({
  templateId,
});
```

### Upload created screenshots

After the first worker has started the screenshot job, the second worker takes care of the next steps:

- Fetch all created screenshots from Websiteshot.
- Download the files temporarily
- Upload the locally available files to S3

For this reason the worker is a bit more extensive:

{% gist https://gist.github.com/urbanisierung/a5a758dc495becc225b0332a4b2857c0 %}

Let's take the Worker apart a bit.

#### Which job?

As a parameter, the worker gets the `JobId` from the process context. The first worker has written the `JobId` returned from Websiteshot to the process context at the end. So easy game!

#### Which screenshots?

We are using the Websiteshot NodeJS client again for this. Easy peasy. Somehow it doesn't get more sophisticated....

#### Intermediate step

In order for us to upload the screenshots to the cloud bucket we need to have them available. We take the easy way and save the screenshots temporarily before uploading them again. For this, we don't need to do anything more than execute a few GET requests. In NodeJS this is done with a few lines of code :)

#### Finale Grande

This is the central task of the worker. The previous three steps were just the preparation for this step. But even this part is pretty manageable with the help of the AWS SDK.

Yikes, are we done already? Yes! In fact, with this process and the associated workers, we've done everything we need to take screenshots of pre-configured URLs.

## And now?

Now comes the concrete example: Camunda Cloud provides a console through which users can manage clusters and clients. Now I want to have screenshots taken from the Console using a test account. For this purpose I have created the following template:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/i17eaeat0jxs924r84hs.png)

I use the process shown above exactly the same way to deploy and run it in Camunda Cloud. To start a new instance you can use [Restzeebe](https://restzeebe.app) again. Once the workers are registered the service tasks are processed.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vxq7y8nmyh19d69f6g1t.png)

The results can be viewed via the Websiteshot Console:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8c7t7ug1ioodl2of530z.png)

And our screenshots end up in S3:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/svk99qve4ncj1xx40x76.png)

So, without further ado, in the last few minutes we built a process that automatically takes screenshots from the Cloud Console. I don't need to mention that the URLs can be replaced quite easily. We can create as many other templates as we want and just reuse the same process. We just need to adjust the header parameter. Pretty cool I think!

You can also view, fork and modify the complete implementation in this repo: [https://github.com/websiteshot/camunda-cloud-example](https://github.com/websiteshot/camunda-cloud-example)

As with the last blog posts in this series: the process can easily be extended or the flow changed. For example, if you want to use the screenshots to automatically update the documentation, you can add an approval process. If you have read the tutorial with the Trello Cards you can for example create a new Trello Card on a specific board. A responsible person can then first look at the screenshots and either approve them for upload or reject them. In case of rejection, a specific message can be sent to a Slack channel because a view is not rendered correctly.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8q6czyoflzs4xczdyca6.jpg)

Another nice use case is the automated generation of social share images of conference speakers: at a conference there are many speakers who like to be announced via social media. Here, a template based on HTML and CSS can be parameterized so that only the parameters need to be changed. A process could eventually generate the social share images and publish them to various social media platforms. Create the template once and sit back!

Maybe this tutorial inspired you to automate the generation of your screenshots with the help of processes. If so, I look forward to your reports! And with the time gained, you can now take care of more important things, such as:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/614a4zuvxj99jq6aiy1n.jpg)

---

Let me know if the article was helpful! And if you like the content follow me on [Twitter](https://twitter.com/urbanisierung), [LinkedIn](https://www.linkedin.com/in/adamurban/) or [GitHub](https://github.com/urbanisierung) :)

---

<span>Header Photo by <a href="https://unsplash.com/@sharegrid?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">ShareGrid</a> on <a href="https://unsplash.com/s/photos/camera?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>

<span>Last Photo by <a href="https://unsplash.com/@remi_b?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Rémi Bertogliati</a> on <a href="https://unsplash.com/s/photos/chill?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>