twolfson / karma-electron

Karma launcher and preprocessor for Electron
The Unlicense
59 stars 21 forks source link

sqlite3 stalls with nodeIntegration true contextIsolation false #57

Closed estebanabaroa closed 2 years ago

estebanabaroa commented 2 years ago

repo with bug example https://github.com/estebanabaroa/karma-electron-sqlite3-bug

example.test.js

describe('try sqlite3', () => {
  it('try sqlite3', async () => {
    console.log('before')
    await new Promise(resolve => {
      const db = new window.sqlite3.Database(':memory:')
      db.close(resolve)
    })
    console.log('after') // this never gets called
  })
})

preload.js

window.sqlite3 = require('sqlite3').verbose()

karma.conf.js

module.exports = function (config) {
  config.set({
    frameworks: ['mocha'],
    client: {
      mocha: {timeout: 60000},
      useIframe: false,
    },
    plugins: [require('karma-electron'), require('karma-mocha')],

    basePath: './',
    files: ['**/*.test.js'],

    customLaunchers: {
      CustomElectron: {
        base: 'Electron',
        browserWindowOptions: {
          webPreferences: {
            nodeIntegration: true,
            contextIsolation: false,
            preload: require('path').resolve(__dirname, 'preload.js'),
          },
          show: false,
        },
      },
    },
    browsers: ['CustomElectron'],

    singleRun: true,
    autoWatch: false,
    port: 9371,
    colors: true,
    logLevel: config.LOG_INFO,
    browserNoActivityTimeout: 60000,
    browserDisconnectTimeout: 60000,
    browserDisconnectTolerance: 5,
  })
}
twolfson commented 2 years ago

It looks like you're missing some of the configurations required by karma-electron as documented in the README (i.e. preprocessors, client.useIframe). Please add those settings and see if that fixes it =/

https://github.com/twolfson/karma-electron#nodejscustom-integration

Additionally, can you verify that electron does run well with those browserWindowOptions outside of the karma-electron context? (thus verifying it's karma-electron that's the issue)

estebanabaroa commented 2 years ago

It looks like you're missing some of the configurations required by karma-electron as documented in the README (i.e. preprocessors, client.useIframe). Please add those settings and see if that fixes it =/

https://github.com/twolfson/karma-electron#nodejscustom-integration

That's correct I had forgot the preprocessors, though I have added it now and still seem to get the same result (never reaching 'after' log)

This is the updated karma.conf.js (I copy pasted the config from readme to be 100% sure):

module.exports = function (config) {
  config.set({
    // Inside `karma.conf.js`
    // Define our custom launcher for Node.js support
    customLaunchers: {
      CustomElectron: {
        base: 'Electron',
        browserWindowOptions: {
          // DEV: More preferentially, should link your own `webPreferences` from your Electron app instead
          webPreferences: {
            // Preferred `preload` mechanism to expose `require`
            preload: __dirname + '/preload.js',

            // Alternative non-preload mechanism to expose `require`
            nodeIntegration: true,
            contextIsolation: false

            // nativeWindowOpen is set to `true` by default by `karma-electron` as well, see #50
          }
        }
      }
    },

    // Use our custom launcher
    browsers: ['CustomElectron'],

    // DEV: preprocessors is for backfilling `__filename` and local `require` paths
    preprocessors: {
      '**/*.js': ['electron']
    },

    // DEV: `useIframe: false` is for launching a new window instead of using an iframe
    //   In Electron, iframes don't get `nodeIntegration` priveleges yet windows do
    client: {
      useIframe: false,
      mocha: {timeout: 60000},
    },

    frameworks: ['mocha'],

    plugins: [require('karma-electron'), require('karma-mocha')],

    basePath: './',
    files: ['**/*.test.js'],

    singleRun: true,
    autoWatch: false,
    port: 9371,
    colors: true,
    logLevel: config.LOG_INFO,
    browserNoActivityTimeout: 60000,
    browserDisconnectTimeout: 60000,
    browserDisconnectTolerance: 5,
  })
}

Additionally, can you verify that electron does run well with those browserWindowOptions outside of the karma-electron context? (thus verifying it's karma-electron that's the issue)

I ran the same browserWindowOptions with electron command and it seems to work, it reaches the 'after' log. It's in this repo: https://github.com/estebanabaroa/karma-electron-sqlite3-bug

git clone https://github.com/estebanabaroa/karma-electron-sqlite3-bug.git && cd karma-electron-sqlite3-bug
yarn
yarn electron # electron main.js -> works 
yarn test # karma start -> fails
twolfson commented 2 years ago

Thank you for providing the repo to reproduce the issue. Unfortunately, I don't have time/bandwidth to attempt to reproduce the issue and dig into it if I can reproduce it =/

Can you keep attempting to debug the issue? Usually at this point I'd try a few things:

I hope this helps =/

estebanabaroa commented 2 years ago

Thank you for providing the repo to reproduce the issue. Unfortunately, I don't have time/bandwidth to attempt to reproduce the issue and dig into it if I can reproduce it =/

Can you keep attempting to debug the issue? Usually at this point I'd try a few things:

* Set `[show: true](https://github.com/twolfson/karma-electron#launcher-configuration)`, use Karma's debug window, and look for any obvious errors in the Dev Tools console

I already tried that unfortunately. Show doesn't change the behavior. The debug window stays blank. The dev tool console becomes "disconnected" as soon as the function is called and doesn't give any logs. Karma with LOG_DEBUG also doesn't say anything related to sqlite3 or shows any error, it just stalls.

* Verify that a basic synchronous action works as expected

I think I'm calling the only available method of sqlite3 at this point, which is to create the db, I'm not sure there's any other method I can call but I dont know this library well.

* Verify that a non Node.js specific asynchronous action works as expected

It works in both node and regular electron, just not karma-electron.

I hope this helps =/

I'm guessing the issue is due to sqlite3 using native modules and it not working somehow. If you have any other ideas for debugging let me know.

twolfson commented 2 years ago

I gave it a whirl and can confirm something is weird with the electron configuration. I really should document the whole "green bar" setup that Karma has as well as needing singleRun: false

but I'm assuming you got to that step just fine based on the message =/

twolfson commented 2 years ago

Hmm, I just gave electron@12 a shot and it seems to work fine, so it might be time for an upgrade on our electron support in this repo =/

Going to reopen this issue with that premise. I don't have time to pick this up any further sadly =/

If you have bandwidth, feel free to give it a shot (and let me know)

Edit: I will address this some time within the next 2 weeks, if it's not addressed by others sooner

estebanabaroa commented 2 years ago

Hmm, I just gave electron@12 a shot and it seems to work fine, so it might be time for an upgrade on our electron support in this repo =/

Going to reopen this issue with that premise. I don't have time to pick this up any further sadly =/

If you have bandwidth, feel free to give it a shot (and let me know)

Edit: I will address this some time within the next 2 weeks, if it's not addressed by others sooner

Are there any instructions for using electron@12? I wouldn't mind having to modify karma-electron temporarily if I could get it to work in the meantime.

twolfson commented 2 years ago

This package was last tested formally against electron@12, https://github.com/twolfson/karma-electron/blob/7.2.0/package.json#L58

electron@12 docs can be found here: https://github.com/electron/electron/tree/v12.2.3/docs

If you're going to spend time trying to downgrade electron on your app, it might be better spent to find what changed/broke this repo instead =/ Usually the changes are minor (e.g. moving from callback to Promise, renamed an API)

twolfson commented 2 years ago

Going to take a shot at the electron@20 upgrade/support now

twolfson commented 2 years ago

Our test suite has broken in electron@15, so digging into those docs now

twolfson commented 2 years ago

Ah, sadly it was a red herring. Just a module.parent change, and the test suite seems to work through electron@20 just fine (albeit looks like a slower launch for the Node.js integration pieces)

twolfson commented 2 years ago

Yea, I'm quite confident the issue is in Electron and/or sqlite3 now ._. Maybe it has something to do with launching a new sqlite3 in an iframe? But if I update the test to do nothing:

describe('try sqlite3', () => {
  it('try sqlite3', async () => {
    console.log('before')

    // await new Promise(resolve => {
    //   const db = new window.sqlite3.Database(':memory:')
    //   db.close(resolve)
    // })

    console.log('after')
  })
})

Show the browser via show: true:

        browserWindowOptions: {
          // DEV: More preferentially, should link your own `webPreferences` from your Electron app instead
          webPreferences: {
            // Preferred `preload` mechanism to expose `require`
            preload: __dirname + '/preload.js',

            // Alternative non-preload mechanism to expose `require`
            nodeIntegration: true,
            contextIsolation: false,

            // nativeWindowOpen is set to `true` by default by `karma-electron` as well, see #50
          },
          show: true
        }

and move to continuous mode:

singleRun: false,

Then I run npm test and enter the debug window and run what would be in the promise, we get Electron disconnecting from Karma intensely:

const db = new window.sqlite3.Database(':memory:')

image

image

image

Closing this issue for now as it's very unlikely related to the launcher =/