twolfson / karma-electron

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

"require is not defined" after update to karma-electron 7 / electron 12 #53

Open trusktr opened 3 years ago

trusktr commented 3 years ago

Tooling is always tricky business. This is what I have in my config:

        browsers: ['CustomElectron'],
        customLaunchers: {
            CustomElectron: {
                base: 'Electron',
                flags: [ '--show' ]

                browserWindowOptions: {
                    nodeIntegration: true,
                    nodeIntegrationInWorker: true,
                    nodeIntegrationInSubFrames: true,
                    contextIsolation: false,
                },
            },
        },

        preprocessors: {
            'dist/**/*.test.js': ['electron', 'webpack', 'sourcemap'],
        },

        client: {
            useIframe: false,
            loadScriptsViaRequire: false, // true makes no difference.
        },

Did I miss something in the newer karma-electron?

twolfson commented 3 years ago

That all looks good to me =/ We run our tests against these versions so it should just work. Sanity check: Have you upgraded to the latest karma-electron as well? =/

trusktr commented 3 years ago

I wonder if maybe it's a side-effect of karma-webpack. The new karma-webpack has an optimization that splits common dependencies into a shared module (the older version made a big bundle for every test file, each bundle having duplicates). This is what one test file looks like:

// /absoluteElementOperations.test.2135415586.js
"use strict";
(self["webpackChunklume"] = self["webpackChunklume"] || []).push([["ElementOperations.test.2135415586"],{},
/******/ __webpack_require__ => { // webpackRuntimeModules
/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
/******/ __webpack_require__.O(0, ["commons"], () => (__webpack_exec__("./dist/core/ElementOperations.test.js")));
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ module.exports = __webpack_exports__;
/******/ }
]);

It is loaded in the karma's html entrypoint like this:

<script type="text/javascript" src="/absoluteElementOperations.test.2135415586.js" crossorigin="anonymous"></script>

and it gives module is not defined on module.exports.

hm. :thinking:

twolfson commented 3 years ago

Yea, using webpack to define its own require/import while also expecting Electron/Node.js' require to just work seems like a big headache to wrangle x_x

trusktr commented 3 years ago

Oh.. My.. Goodness... those above options have to be inside the webPreferences object. Doh!

                browserWindowOptions: {
                    webPreferences: {
                        nodeIntegration: true,
                        nodeIntegrationInWorker: true,
                        nodeIntegrationInSubFrames: true,
                        contextIsolation: false,
                    }
                },

It's all working smoothly now (but still with Webpack, and the output as CommonJS).

trusktr commented 3 years ago

I still keep getting these errors, but only in debug mode with a window open, regardless if I have the proper config.

In "debug mode" I set singleRun to false, and browserWindowOptions.show to true. In this mode, even if client.loadScriptsViaRequire is true, I get require is not defined.

When I run tests without debug mode enabled, console.log statements that come after any require() call show up in the terminal output just fine. It just isn't working in the debug window.

Any ideas?

twolfson commented 3 years ago

Shot in the dark: It sounds like something in your singleRun: false is messing with you (e.g. test environment isn't properly being cleaned, or maybe something is overzealously removing require)

trusktr commented 3 years ago

Hmm. Yeah, no idea why something would be different. This is the first file I have in files:

// karma-augment-node-path.js
const path = require('path')
process.env.NODE_PATH = path.resolve(process.cwd(), 'node_modules') + ':' + process.env.NODE_PATH
require('module').Module._initPaths()
console.log('################################################################')
console.log('################################################################')
console.log('################################################################')
console.log('################################################################')
console.log('################################################################')

When I run with singleRun: true, I see this in my terminal output:

...
22 09 2021 12:17:20.242:INFO [launcher]: Starting browser Electron
22 09 2021 12:17:20.669:INFO [Electron 14.0.1 (Node 14.17.0)]: Connected on socket eMIRJxV7RjNPNWytAAAB with id 67478283
Electron 14.0.1 (Node 14.17.0) LOG LOG: '################################################################'
Electron 14.0.1 (Node 14.17.0) LOG LOG: '################################################################'
Electron 14.0.1 (Node 14.17.0) LOG LOG: '################################################################'
Electron 14.0.1 (Node 14.17.0) LOG LOG: '################################################################'
Electron 14.0.1 (Node 14.17.0) LOG LOG: '################################################################'
...

When I run with singleRun: false, I see this in my terminal, and similar in Electron console (just the require errors, not the other terminal output):

...
22 09 2021 12:28:40.750:INFO [launcher]: Starting browser Electron
22 09 2021 12:28:41.220:INFO [Electron 14.0.1 (Node 14.17.0)]: Connected on socket 8PCN10VDBPVkc12tAAAB with id 6745101
22 09 2021 12:28:56.969:WARN [Electron 14.0.1 (Node 14.17.0)]: Disconnected (0 times) Client disconnected from CONNECTED state (transport close)
Electron 14.0.1 (Node 14.17.0) ERROR
  Disconnected Client disconnected from CONNECTED state (transport close)
22 09 2021 12:28:57.046:INFO [Electron 14.0.1 (Node 14.17.0)]: Connected on socket v_9MI5_w9DYWsB0dAAAD with id 6745101
Electron 14.0.1 (Node 14.17.0) ERROR
  An error was thrown in afterAll
  Uncaught ReferenceError: require is not defined
  ReferenceError: require is not defined
      at /home/trusktr/src/lume+lume/packages/cli/config/karma-augment-node-path.js:2:14
...

May the disconnected error have to do with it? I think that's just the open/refreshing of the debug window, right?

trusktr commented 3 years ago

I confirm the only difference in my config is singleRun:true (working) vs singleRun:false (not working).

trusktr commented 3 years ago

Ok, I found a clue, but not sure what it points to.

I noticed that when I first open the debug window and subsequently open the console, I see the expected ######... output and no require is not defined errors.

It is only after I refresh the debug window that the errors happen. All subsequent runs after the first have the error.

This explains why when singleRun is true the tests pass and the whole process exits with 0; because the first run is always fine.

The combination of my mistake, plus the fact that refreshing the Electron breaks it, totally did not help because no matter what options I tried, even if they were correct, things continued to not work.

The question is, why are require and friends not available after refresh of the Electron window? This seems like an Electron bug.

trusktr commented 3 years ago

(No luck updating from Electron 14.0.1 to 15.0.0. Electron 15 completely crashes on any refresh attempt with devtools saying DevTools was disconnected from the page. Once page is reloaded, DevTools will automatically reconnect.)

trusktr commented 3 years ago

^ I think the issue is in Electron itself: karma-electron has launched Electron using new BrowserWindow like normal, and it even all works fine on first run, but then a refresh of the window causes Node APIs (require, module, etc) to be is not defined.

I don't think there is any possible option that karma-electron could define that would cause Electron to disable Node integration upon refresh of an Electron window. I don't think there is any such Electron option for that behavior. Something seems wrong in Electron.

twolfson commented 3 years ago

Now that we discovered setWindowOpenHandler wasn't set so settings didn't propagate (#54), it might be worth trying out 7.1.0 to see if this fixes it. Though, I'm doubtful since our tests still didn't raise any issues =/