First steps with end-to-end testing using jest + playwright (puppeteer)

kodziak

Przemysław Paczoski

Posted on December 3, 2020

First steps with end-to-end testing using jest + playwright (puppeteer)

Oryginally posted at: https://kodziak.com/blog/first-steps-with-e2e-testing-using-jest-playwright

This post is a continuation of the “First steps with test automation” article.

Recently I wrote a post about my first steps with test automation. I tried to answer questions related to the topic and guide you where and what to search for (if you're interested - click here!). Now, I want to expand on it with technical steps you need to take and show you how easily you can create a basic test with a real world example (my blog 🥳).

We will create a base repository with Playwright and JestJS and write a basic test which will:

  • Load the blog page,
  • Check if the blog title contains the author’s name,
  • Check if the posts list isn't empty,
  • Click on the first post title and check if it loaded correctly.

To achieve it, I think you need a little more knowledge, so I split the article into three topics (+bonus):

  • What do I need to start with automation?
  • Project setup with Playwright and JestJS
  • Let's write an automated test
  • Bonus: Test recorder!

Before starting the game, here are some topics which you should be familiar with:

  • Basic knowledge of JavaScript,
  • You know how to use CLI and NPM/Yarn,
  • You're familiar with HTML/CSS.

What do I need to start with automatization?

First of all, you need a library/tool which allows you to control a browser using code. Today, I'll use NodeJS library called Playwright (which is very similar to Puppeteer – here you can find a nice article about the differences: https://blog.logrocket.com/playwright-vs-puppeteer/) to automate our actions with an API. You need a tool like this to write tests that will imitate the behaviour of end user (behave like our clients).

Basically, doing a test manually, you're using a mouse to click and scroll or a keyboard to fill in the forms. In automated tests, you're using a library API to do the same things but the browser is controlled by automation software, not a user.

Next, we need assertions. Playwright provides their own ones, but honestly – I've never used them. I like JestJS, which, besides that, is a test runner, which gives you more opportunities to control the whole test base. With an easy way to do parallelisation or configs for dev/production envs, writing tests is only a pleasure 🥰.

In summary, you need:

  • A library to control a browser → we'll use Playwright,
  • A test runner → we'll use JestJS

Project setup with Playwright and JestJS

So we will use:

And if you decided to stick with puppeteer:

Note: When using puppeteer, you need to change selectors because the API is slighty different. In our basic test, it is enough to remove css= part and change waitForLoadStatewaitForNavigation. After those two changes, everything should work.

Before we start writing our first automated test, we need to set up the repository:

Let's initialize it first:

  • yarn init or npm install
  • git init

Then install the required dependencies:

yarn install jest jest-playwright-preset playwright

or

npm install jest jest-playwright-preset playwright

And create two config files,

// jest.config.js
module.exports = {
  preset: 'jest-playwright-preset',
}
Enter fullscreen mode Exit fullscreen mode
// jest-playwright.config.js
module.exports = {
    // Describe which browsers we want to run
  browsers: ['chromium', 'firefox', 'webkit'],
  launchOptions: {
        // If we want to run browsers in headless mode or not,
    headless: false,
        // If we want to have opened devtools from start
    devtools: false,
  }
}
Enter fullscreen mode Exit fullscreen mode

Also, we need to an execute script to our package.json:

"scripts": {
    "test": "jest"
  },
Enter fullscreen mode Exit fullscreen mode

Now, you can yarn test or npm run test which will run all files matching *.test.js names – but we don't have any tests yet 🙈

One more thing that I added is tests/ directory where we will store our test.

Let's write an automated test

First we need to know what we want to test 🙈

I created a basic flow relating to my blog, which you're reading now:

  • Check if the blog title contains the author’s name,
  • Check if the posts list isn't empty,
  • Click on the first post title and check if it loaded correctly.

In the directory tests/ I added a file example.test.js. And to make it easier for you, I coded the above scenario, adding comments line by line, describing what’s happening.

let blogPosts = [];

describe('Blog - kodziak.com/blog/', () => {
    // Will trigger methods before tests
  beforeAll(async () => {
    // Load blog page
    await page.goto('https://kodziak.com/blog/');
  })

  test('title should be "Blog | Przemysław Paczoski"', async () => {
    // Get website title
    const title = await page.title();

    // Compare title of current page
    expect(title).toBe('Blog | Przemysław Paczoski');
  })

  test('should display list of blog posts', async () => {
    // Get all blog posts as an array of objects
    blogPosts = await page.$$eval('css=.post', elems => elems.map(el => {
      return {
        title: el.querySelector('.post-title').textContent.trim(),
        description: el.querySelector('.post-description').textContent.trim(),
        href: el.href,
      }
    }));

    // Check if list length is greater than 0
    expect(blogPosts.length).toBeGreaterThan(0);
  })

  test('click on blog post should redirect to article', async () => {
        // Go to first blog post, there we're waiting to resolve all promises from array
    await Promise.all([
      // Click oo .post-title css class element
      page.click('css=.post-title'),
      // Wait for networkidle event, promise resolves after event
      page.waitForLoadState('networkidle')
    ]);

    // Get title, content and href of current article
    const [articleTitle, articleContent, articleHref] = await Promise.all([
      // Get article title, we use here array destructuring
      page.$eval('css=h2', el => el.textContent.trim()),
      // Get article content
      page.$eval('css=.content', el => el.textContent),
      // Get article href
      page.url()
    ]);

    // Destructuring first element from an blog posts array. First we use array destructuring and then object destructuring
    const [{title, description, href}] = blogPosts;

    // Compare title from posts list with current article's title
    expect(title).toBe(articleTitle);
    // Check if the current article content includes description from posts list, compare output with boolean true
    expect(articleContent.includes(description)).toBe(true);
    // Compare href from posts list with current article's href
    expect(href).toBe(articleHref);
  })
})
Enter fullscreen mode Exit fullscreen mode

After we finish coding our test, let's run it using the command yarn test.

Playwright will open three browsers which we described earlier: chromium, firefox, webkit.

And if everything goes well, we should see the following log:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/078899a2-7963-484e-a55c-3379ca482c54/Untitled.png

And that's it! We ran our tests positively in three different browsers.

Bonus: Test recorder!

Lastly, a good way to start with test automation could be to use test recorders. Nice one, created with playwright is: https://github.com/microsoft/playwright-cli which allows you to record your browser interactions and automatically generate a fully working code – an automated test with Playwright.

Conclusion

In this article, I wanted to show you how easy it is to automate a basic test scenario using tools such as Playwright and JestJS. I hope that will be a good start for you to explore this part of software engineering.

After reading it, you should have learned:

  • What Playwright (Puppeteer) and JestJS are used for,
  • How to set up a repository using those technologies,
  • How to write a basic test.

Fully working, implemented code from this article can be found in my repository: https://github.com/Kodziak/playwright-first-steps

Have a nice day!

💖 💪 🙅 🚩
kodziak
Przemysław Paczoski

Posted on December 3, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

What was your win this week?
weeklyretro What was your win this week?

November 29, 2024

Where GitOps Meets ClickOps
devops Where GitOps Meets ClickOps

November 29, 2024