jeudi 27 février 2020

Jest + puppeteer best architecture practices

I just entered the world of testing with puppeteer and jest, and I was wondering what the best practice was in terms of folder architecture and logic.

I've never done testing before and I think I'm getting a little lost in the different principles and concepts and how it all fits together.

I learned to do my tests based on the page-object model, so I have classes for each of my pages, but also for each of my modules ( or component ). For example, in my application, the header or the login modal are components.

Then I have a test file per page or per component. (for example the landingPage.tests.js file, which uses the model of the LandingPage class in the LandingPage.js file)

Here is a concrete example: I have different login cases and I'd like to test them all. For example I want to test to connect with a "normal" user, for which the process is simply login then password. Then I need to test with a user who has activated 2FA, or with a user from a company that uses SSO.

I first thought about putting my different tests in authentication.tests.js, in different "describe" blocks, thinking it would open a new tab each time, but it doesn't... I use puppeteer in incognito mode to make sure each tab is an isolated session.


So my questions are:

  • Where is the best place to do these test suites?

  • Am I supposed to have test files that "describe" the pages ( for example, the button must be present, such text must be here etc) and also have "scenario type" test file ( a set of contextual actions to a user, like for my different login cases) ?

Here is authentication.tests.js, in which I would like to tests all my different ways of logging in :

import HeaderComponent from "../../../pages/components/HeaderComponent";
import AuthenticationComponent from "../../../pages/components/AuthenticationComponent";
import LandingPage from "../../../pages/landing/LandingPage";

import {
    JEST_TIMEOUT,
    CREDENTIALS
} from "../../../config";


describe('Component:Authentication', () => {
    let headerComponent;
    let authenticationComponent;
    let landingPage;

    beforeAll(async () => {
        jest.setTimeout(JEST_TIMEOUT);
        headerComponent = new HeaderComponent;
        authenticationComponent = new AuthenticationComponent;
        landingPage = new LandingPage;
    });


    describe('Normal login ', () => {

        it('should click on login and open modal', async () => {
            await landingPage.visit();
            await headerComponent.isVisible();
            await headerComponent.clickOnLogin();
            await authenticationComponent.isVisible();
        });

        it('should type a normal user email adress and validate', async () => {
            await authenticationComponent.typeUsername(CREDENTIALS.normal.username);
            await authenticationComponent.clickNext();
        });

        it('should type the correct password and validate', async () => {
            await authenticationComponent.typePassword(CREDENTIALS.normal.password);
            await authenticationComponent.clickNext();
        });

        it('should be logged in', async () => {
            await waitForText(page, 'body', 'Success !');
        });

    });

    describe('SSO login ', () => {
        // todo ...
    });


});

Thank you and sorry if it sounds confusing, like I said I'm trying to figure out how it all fits together.

Aucun commentaire:

Enregistrer un commentaire