Pedro
Pedro

Reputation: 43

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).

Upvotes: 4

Views: 786

Answers (2)

Harry Eastwood
Harry Eastwood

Reputation: 1

If it's reading a barcode's value you want, here's a command I built using a nice barcode decoder on the internet by Orca Scan. The barcode value will end up in the text box and it accepts a wide range of barcode types.

Cypress.Commands.add('readBarcode', (file, value) => {
cy.visit('https://orcascan.com/tools/online-barcode-decoder').wait(1000);

cy.get('.file-upload-wrapper > input').selectFile(file, {
    action: 'drag-drop'
}).wait(500);

cy.get('[type="text"]').invoke('val') // Get the value of the textbox
    .should('include', value);});

Simply provide it with an image (png, jpg, svg) of a barcode and the expected value like so:

cy.readBarcode('imagepath/image.jpg', 'barcodevalue');

Upvotes: 0

Zoe
Zoe

Reputation: 218

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.

Upvotes: 6

Related Questions