DEV Community

Cover image for Gremlins testing with puppeteer
Przemyslaw Jan Beigert
Przemyslaw Jan Beigert

Posted on • Edited on

5 3

Gremlins testing with puppeteer

Introduction

The idea behind gremlins testing is pretty simple: any user action on your application should not have throw a runtime error. It's like a smoke test with lots of random user's actions. This should be helpful when your project has unit tests but you're not ready yet for end to end tests.

Implementation

  • Install the lib: yarn add gremlins.js -D
  • Copy gremlins to hosted directory (e.g. dist) cp node_modules/gremlins.js/dist/gremlins.min.js dist
  • Open your app in a browser
  • In the browser console add gremlins to DOM const s = document.createElement('script'); s.src='gremlins.min.js'; document.head.appendChild(s);
  • Run the gremlins gremlins.createHorde().unleash()
  • In result gremlins will execute buch od random events

Image description

If in console there's no error test passes

Automatisation

Of course we can not run it manually each time. To automate it we can use the puppeteer, it's a nodeJS chromium driver. After installation yarn add puppeteer -D do something like this:



// run-gremlins.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  const errors = [];
  page.on('pageerror', (error) => {
    browserErrors.push(error);
  });
  await page.goto('localhost:4200');
  if (browserErrors.length !== 0) {
    errors.forEach((e) => {
      console.error('e2e error: ', e);
    });
    process.exit(1);
  }

  // TODO: insert gremlins
  // TODO: run gremlins
  // TODO: wait 5s

  await browser.close();
})();


Enter fullscreen mode Exit fullscreen mode

This code will run a browser (in incognito mode to have cookies cleared), open new a page on localhost:4200, run gremlins like in the previous part and if any page error appears process will close with falsy status.

missing parts:



module.exports.insertGremlins = async (page) => {
  await page.evaluate(() => {
    const s = document.createElement('script');
    s.src='gremlins.min.js'; 
    document.head.appendChild(s);
  });
};

module.exports.runGremlins = async (page) => {
  await page.evaluate(() => {
    window.gremlins.createHorde().unleash()
  });
};

module.exports.wait = (time) =>
  new Promise((resolve) => {
    setTimeout(resolve, time);
  });


Enter fullscreen mode Exit fullscreen mode

Verification

To be sure that gremlins are gonna catch an error, add something like this to the app: setTimeout(() => { throw new Error('debug'); }, 3000); . If command node run-gremlins.js will exit with falsy code then the tester works correctly :)

Run on docker

Best way to be sure that tester is working on other environment (like CI) is wrap it into a docker container. Unfortunately we need to install some dependencies in the container.



FROM node:16.13.1 # Specific version, not the lastest

RUN ["apt-get", "update"]
RUN apt-get install gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils -y
RUN apt-get update \
     && apt-get install -y wget --no-install-recommends \
     && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
     && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
     && apt-get update \
     && apt-get install -y google-chrome-unstable --no-install-recommends \
     && rm -rf /var/lib/apt/lists/* \
     && wget --quiet https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh -O /usr/sbin/wait-for-it.sh \
     && chmod +x /usr/sbin/wait-for-it.sh


Enter fullscreen mode Exit fullscreen mode

To allow root user run puppeteer add --no-sandbox flag into run-gremlins.js file:



const browser = await puppeteer.launch({
  args: ['--no-sandbox'],
});


Enter fullscreen mode Exit fullscreen mode

In this case your local web application has to run in the same container, however you can add --network=host to the previous command to allow gremlin-tester to communicate with a localhost.

Conclusion

I'm using it, it saves a lot of my time. Maybe someone else will to take advantage of it.

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (0)

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay