How to make Electron wait for npm start to finish - angularjs

I have the following situation: I have a Angular CLI app, which is started by npm start. This operation may take some time to finish. After the start, the app is available at localhost:3000.
We then have an Electron app (made with nativefier module) which makes an app out of the url localhost:3000.
The problem arises when I start the Angular app and, in parallel, the Electron app, with a batch file. Obviously the Electron app will show an error as NPM start is not finished yet. On the other hand, I can't execute NPM start and the app sequentially, as the end user should not see the CMD window of NPM start (which I hide with a VBS script).
Ideally, the best solution would be that the Electron app and npm start fire on parallel and the Electron app would show a loading screen while NPM start is performing.
I have literally no idea how to achieve this.
Could someone address me to a solution?
Thanks
Fabio

The solution I found consists in having two different windows and playing with them, hiding the first one and show the second one when the latter is ready... So, imagine you want to show Google.com while waiting that localhost is ready
const {app, BrowserWindow} = require('electron')
let win
let win2
function createWindow () {
let win = new BrowserWindow({backgroundColor: '#2e2c29'})
win = new BrowserWindow({width: 800, height: 600, show:false})
win2 = new BrowserWindow({width: 800, height: 600})
win.loadURL('http://localhost:3000')
win2.loadURL('http://www.google.com')
win.once('ready-to-show', () => {
win.show()
win2.hide()
win2.close()
})
win.on('closed', () => {
win = null
})
}
app.on('ready', createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (win === null) {
createWindow()
}
})

Related

Electron React app white screen + disconnected devtools in build but fine in development?

When I run my app on the development server (npm start) it works fine without any issues in the console.
However, when I build my app (npm run build && electron-builder -m) I get a white screen and disconnected devTools.
Here is my main.js file
const { app, BrowserWindow, screen } = require('electron')
let mainWindow;
function createWindow () {
// Create the browser window.
const { width, height } = screen.getPrimaryDisplay().workAreaSize
const win = new BrowserWindow({
title:"DSL viewer",
width:1050,
height:700,
maxHeight:height,
maxWidth:width,
minHeight:700,
minWidth:1050,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
devTools: true
}
})
win.loadURL('./index.html');
win.on('closed', function () {
mainWindow = null;
});
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
Here is a screenshot of what the app looks like
Does anyone know what may be causing this or how I can go about debugging it?
Thanks in advance!
It is because electron is unable to find the index.html after build. Change window.loadURL to window.loadURL(__dirname+"/index.html").

Webview context doesn't show up anymore when testing using Appium

I am creating an automation test using Appium and webdriverio:
const wdio = require("webdriverio");
const opts = {
path: "/wd/hub",
port: 4723,
capabilities: {
platformName: "Android",
platformVersion: "11",
deviceName: "Android Emulator",
app: "/path/to/myapk.apk",
automationName: "UiAutomator2",
autoGrantPermissions: true
}
};
async function main() {
const driver = await wdio.remote(opts);
const contexts = await driver.getContexts();
console.log("Contexts:", contexts);
await driver.deleteSession();
}
main();
The problem
When running tests I could see that I used to have two contexts:
NATIVE_APP
WEBVIEW_chrome (or similar, I do not remember exactly the value here)
I then made a change which switched contexts to the webview, there I got an error about the chrome driver not being found. That is when I installed it: npm install "appium-chromedriver".
I do not know if this is what made everything go babanas, but since then, everytime I test, I can only see the native context, no more webview context :(
More info
It is important to point out that I have modified my Android app to include this:
#Override
public void onCreate() {
super.onCreate();
WebView.setWebContentsDebuggingEnabled(true);
}
I can also start chrome://inspect and see the webview is there and even inspect it. But when running tests, the driver cannot see the webview context.
Why? How to fix this?
Turns out that I need to wait for a webview to show up in the app, so this works:
async function main() {
const driver = await wdio.remote(opts);
// Wait a few seconds so the webview properly loads
await new Promise(resolve => setTimeout(resolve, 5000));
const contexts = await driver.getContexts();
console.log("Contexts:", contexts);
await driver.deleteSession();
}

Cypress ReactJs tests Fail to find elements on Gitlab CI

I am testing some Reactjs UI with Cypress. When I run the tests locally using localhost:3000, the tests pass but when I push to Gitlab CI, the tests fail and the error is as shown below.
CypressError: Timed out retrying: Expected to find element: '.css-iyxtew', but never found it.
This is not due to server delay, I have tried adding wait time in vain. My guess is that the localhost server on Gitlab is not okay. Please help me with any solutions.
beforeEach(() => {
cy.visit('localhost:3000')
eslint-disable-next-line no-return-assign
cy.window().then(win => win.onbeforeunload = undefined)
})
it('Does not do much!', () => {
expect(true).to.equal(true)
})
it('.should() - make an assertion about the current page', () => {
cy.get('[data-cy=loader]').find('h6').should('be.visible')
cy.get('body').should('be.visible')
cy.get('.css-iyxtew').should('be.visible')
cy.get('[data-cy=index-page]').find('[data-cy=heading]').should('be.visible')
cy.get('.css-iyxtew').find('li').should('have.length', 2)
.find('.login').find('.css-17nm302-Button')
.should('have.css', 'background-color', 'rgba(0, 0, 0, 0)')
cy.get('.main-section').should('exist').find('.left-nav ').should('exist')
.find('.left-margin-pane').should('exist')
cy.get('.heading').find('.sub-heading')
.contains('Choose a phase below to browse our growing collection of adaptive implementation resources')
})
The solution I found out after some time is that I needed to add env variables to the CI environment too for the server to run.
this is gitlab-ci.yml
variables:
GET_PHASE_KITS: $GET_PHASE_KITS
GET_KIT: $GET_KIT
GET_PHASE_ASSETS: $GET_PHASE_ASSETS
GET_USER: $GET_USER
CREATE_USER: $CREATE_USER
ADD_USER_KIT: $ADD_USER_KIT
GET_USER_BY_ID: $GET_USER_BY_ID
GET_PHASES: $GET_PHASES
ADD_USER_ASSET: $ADD_USER_ASSET
GET_ASSET: $GET_ASSET
GET_PHASE: $GET_PHASE
EDIT_USER: $EDIT_USER

ReactJS - large video files make computer to freeze after npm start

I've got my small react web app that runs with no problems while having five low quality videos.
But once I add multiple large high quality video files and I start the app, my laptop freezes and I need to manually shut it down.
//outside the component class
function importAll(r){
let images = {};
r.keys().forEach((item) => { images[item.replace('./', '')] = r(item); });
return images;
}
componentDidMount() {
const videos = importAll(require.context('./videos', false, /\.mp4$/));
window.addEventListener('scroll', this.handleScroll);
}
My videos folder is on my src folder, Any advice?
Thanks in advance to anyone who can help!

How to make the dev tools not show up on screen by default in Electron?

I am using electron-react-boilerplate to create an Electron-React app. The dev tools show up on the screen by default. How can I make the dev tools only appear when I ask for them and not show up on launch?
Also, there are no errors shown in the console, so the dev tools are not showing up because there's an error.
Just comment or remove this line of code in main.js file (setting devTools to false) this.mainWindow.openDevTools();
(or)
Add the following code to
mainWindow = new BrowserWindow({
width: 1024,
height: 768,
webPreferences: {
devTools: false
}
});
(or)
change the package.json build to npm run build && build --win --x64
(or)
again install npm
If we add devTools: false in webPreferences, DevTools will not show when you start the Electron app. However, it can still be opened by pressing Ctrl + Shift + I.
webPreferences: {
devTools: false
}
Have a look at Slack. It is made with Electron and DevTools does not open when you press Ctrl + Shift + I.
I've had a look at Electron's official documentation, and I found a solution which doesn't allow DevTool's to open when you press Ctrl + Shift + I.
const { app, globalShortcut } = require('electron');
app.on('ready', () => {
// Register a shortcut listener for Ctrl + Shift + I
globalShortcut.register('Control+Shift+I', () => {
// When the user presses Ctrl + Shift + I, this function will get called
// You can modify this function to do other things, but if you just want
// to disable the shortcut, you can just return false
return false;
});
});
But, this will block all other browser's Ctrl + Shift +I
So, you can write the above code whenever your electron app is focused. And, remove it when your app is blur. This way you get a proper solution for this issue.
What makes the Developer Tools appear when the app starts is the line require('electron-debug')() in src/main/main.ts. This function has a showDevTools option which defaults to true, so you should change it to false:
require('electron-debug')({ showDevTools: false });
You will still be able to show the Developer Tools with the shortcut Ctrl + Shift + I or pressing F12, if you want to disable it completely, set webPreferences.devTools to false on new BrowserWindow:
mainWindow = new BrowserWindow({
// ... other settings
webPreferences: {
// ...
devTools: false,
},
});
Just add there these two bold line of code. You will not see devTool after packaging.
const electron = require('electron')
// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow
var debug = false
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({width: 800, height: 600})
// and load the index.html of the app.
mainWindow.loadURL(`file://${__dirname}/index.html`)
// Open the DevTools.
if(debug) mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
Every answer mentions that the keyboard shortcut CTRL + SHIFT + I still works even after disabling devtools using devTools: false.
This is because of the registered accelerator in the Electron BrowserWindow's default menu. All you have to do is remove the menu using mainWindow.removeMenu() and none of the development related shortcut keys will work again. Even the ones like CTRL + R which reloads the page.
Just want to add that, if you want to disable devTools only when in production mode, you can do:
new BrowserWindow({
webPreferences: {
devTools: !app.isPackaged,
},
})
P.S. This also prevents using shortcuts like Ctrl+Shift+I to toggle the devTools.
Just remove the line
mainWindow.webContents.openDevTools(false);
YEAR 2022
Code that loaded the devtools is in src/main/main.ts
Search this following code:
const isDebug =
process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true';
if (isDebug) {
require('electron-debug')();
}
you need to disable electron debug by comment it
//require('electron-debug')();

Resources