Search code examples
testingcypressqr-codeui-automation

Scanning QR codes with Cypress: guidance needed


"I am running some tests in Cypress where, in one of the steps, I have to go through the sign-up process, and then it asks me to scan a QR code. For that, I execute the following lines of code to scan the QR code and generate the OTP."

I am using the following library: @nuintun/qrcode

import import {qrcode, decodedQr} from "@nuintun/qrcode";

cy.get('img[alt="QR Code"]').then(async (image) => {
        const src = image.prop('src');
        console.log('Image source:', src);
        const decoded = await qrcode.scan(src);
        const totp = OTPAuth.URI.parse(decoded.data);
        const generateOTP = totp.generate();
        cy.get('input#code').type(generateOTP);
    });

I am getting the following error, after I execute the test: TypeError: Cannot read properties of undefined (reading 'scan') at Context.eval (webpack:///./cypress/e2e/tests/invitation-portal-invitation.cy.js:76:37).


Solution

  • Take a look at what you have imported, you will find it's undefined.

    import { qrcode } from "@nuintun/qrcode";
    console.log(qrcode)   // undefined
    

    If you drop the braces, you find there's a Decoder class, plus some other stuff.

    import qrcode from "@nuintun/qrcode"
    console.log(qrcode)   //   { Decoder, Encoder, ...}
    

    So, following the docs - Decode

    import { Decoder } from '@nuintun/qrcode';
    
    const qrcode = new Decoder();
    
    qrcode
      .scan('https://nuintun.github.io/qrcode/examples/qrcode.jpg')
      .then(result => {
        console.log(result.data);
      })
      .catch(error => {
        console.error(error);
      });
    

    you roughly want this

    import {Decoder} from "@nuintun/qrcode"
    const qrcode = new Decoder();
    
    it('tests my qrcode', () => {
      cy.get('img[alt="QR Code"]').then(image => {
        const src = image.prop('src')
        qrcode.scan(src).then(result => {
          ...
    

    Don't do async/await inside a Cypress callback. Maybe it works, but maybe Cypress throws you an error because you return a promise from inside a callback.

    Just keep it simple, use .then() as documented.