Search code examples
javascriptreactjsaws-amplify

Testing with puppeteer an AWS amplify react app


I would like to test a react application with AWS amplify authentication ( using cognito).

The first step is log in to the app filling the input fileds (email and password) and submit the login form

await page.waitForSelector("#email"); await page.type("#email", "email@example.com", {delay: 500});

await page.waitForSelector("#pass"); await page.type("#pass", "secret", {delay: 500});

then the submit event

But with amplify it didn't works - the input elements are not finded

The form is the following

form login amplify

As you can see the html element form username is just input#username , but if I try to select sthe elemtns with plain JS , it doesnt work

i cant find the input elements

How could I set the value to the form fields and submit the form for puppeter


Solution

  • This is due to the username and password input being in the shadow dom, that's why it's not able to find it. Check out https://github.com/Georgegriff/query-selector-shadow-dom , this tool will make your life easier.

    Here is a made up example using the Amplify default SignIn modal:

    const { Given, When, Then, setDefaultTimeout } = require('@cucumber/cucumber');
    const {  QueryHandler, } = require("query-selector-shadow-dom/plugins/puppeteer");
    
    const puppeteer = require('puppeteer');
    
    setDefaultTimeout(60 * 1000);
    
    
    Given('I visit the myWebsitewebsite', async function () {
        this.browser = await puppeteer.launch({
            headless: true,
            devtools: false
        });
        this.page = await this.browser.newPage();
        await puppeteer.registerCustomQueryHandler('shadow', QueryHandler);
        await this.page.goto('https://example.mywebsite.com', {
            waitUntil: 'networkidle0',
        });
    });
    
    When('enter my credentials', async function () {
        const userNameField = await this.page.waitForSelector("shadow/#username");
        const passWordField = await this.page.waitForSelector("shadow/#password");
        
        await userNameField.type("xxxxxxxxx");  
        await passWordField.type("xxxxxxxxxxx");
        await this.page.keyboard.press("Enter")
    });
    
    Then('I see my dashboard', async function () {
        await this.page.waitFor("#dashboard-card");
        await this.browser.close();
        
    });