nimiq / qr-scanner

Lightweight Javascript QR Code Scanner
https://nimiq.github.io/qr-scanner/demo
MIT License
2.35k stars 509 forks source link

Question about mocking the camera feed with overriding `getUserMedia` #249

Open BeeMargarida opened 3 months ago

BeeMargarida commented 3 months ago

Hi! I'm trying to write e2e tests with Playwright and test the functionality of testing different QRCodes in the same test. I'm facing some issues specific to the functionality of this library and would like to ask if someone could help me.

I was trying to override the getUserMedia to return a stream of the QRCode I want to show, but even though the video feed shows the correct image, the library doesn't seem to scan the QRCode. Is there something specific that I should be doing or any quirk of the library that doesn't allow for this?

The code that mocks the getUserMedia:

const content = await readFile(`${__dirname}/../../fixtures/${image}.png`, { encoding: 'base64' });
await this.page.evaluate(async ({ content }) => {
    const canvas = document.createElement('canvas')
    canvas.id = 'mock-camera'
    canvas.height = 750
    canvas.width = 700
    canvas.hidden = true

    const context = canvas.getContext('2d')
    const image = new Image()

    const promise = new Promise((resolve) => {
        image.onload = () => {
            if (!context) return

            context.drawImage(image, 0, 0)

            const stream = canvas.captureStream()
            navigator.mediaDevices.getUserMedia = () => Promise.resolve(stream)
            resolve(true)
        }
    })
    image.src = `data:image/png;base64,${content}`
    document?.querySelector("body")?.appendChild(canvas)

    await promise
}, { content });

I run this code before opening a modal that contains the QRScanner (and it's initialization).