Skip to content

Commit

Permalink
Upgrade Electron to v25 to related deps (#772)
Browse files Browse the repository at this point in the history
* Initial work of upgrade electron to v25

* Fix devtools injection

* Fix about menu

* Remove devtools-installer setup

* Move context-menu setup to main process

* Remove devtron

* Use fs.watchFile

* Fix url-handle ip listen

* Fix dialog

* Migrate from spectron to playwright

* Update CI

* Remove spectron

* CI: Use node 16

* Remove electron-rebuild & update script

* Use patch-package for patch react-dev-utils

* Add --no-notarize arg for easy build mac app on local

* Bump electron-packager & related deps

* Update CD

* Move playwright-core to dev deps

* Update docs/contributing.md

* CI: Use windows-2022

* CI/CD: Increase network-timeout for windows

* Fix app notariztion

* E2E: Use wait-for-expect

* Update window options

* CI: Cancel previously in-progress run
  • Loading branch information
jhen0409 authored Jul 18, 2023
1 parent 3b85aac commit 1b04eeb
Show file tree
Hide file tree
Showing 29 changed files with 773 additions and 1,631 deletions.
36 changes: 20 additions & 16 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,52 @@ name: CI

on: [push, pull_request]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
build-test-macos:
runs-on: macOS-latest
build-test-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 10.x
- name: CI
node-version: 16.x
- name: Setup
run: sudo apt-get install -y libgbm-dev
- name: Test
run: |
yarn
cd npm-package && yarn && cd ..
yarn test
yarn build
yarn test-e2e
build-test-linux:
runs-on: ubuntu-latest
xvfb-run --auto-servernum yarn test-e2e
build-test-macos:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 10.x
- name: CI
node-version: 16.x
- name: Test
run: |
export DISPLAY=:99.0
Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
npm i -g xvfb-maybe
yarn
cd npm-package && yarn && cd ..
yarn test
yarn build
xvfb-maybe yarn test-e2e
yarn test-e2e
build-test-windows:
runs-on: windows-2019
runs-on: windows-2022
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 10.x
- name: CI
node-version: 16.x
- name: Test
shell: bash
run: |
yarn config set network-timeout 500000 -g
yarn
cd npm-package && yarn && cd ..
yarn build
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ on: release

jobs:
release-linux:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 10.x
node-version: 16.x
- name: Package
run: |
yarn
Expand All @@ -22,15 +22,16 @@ jobs:
pattern: release/react-native-debugger*
github-token: ${{ secrets.GITHUB_TOKEN }}
release-windows:
runs-on: windows-2019
runs-on: windows-2022
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 10.x
node-version: 16.x
- name: Package
shell: bash
run: |
yarn config set network-timeout 500000 -g
yarn
yarn build
yarn pack-windows
Expand Down
134 changes: 46 additions & 88 deletions __e2e__/app.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,42 @@ import fs from 'fs';
import path from 'path';
import net from 'net';
import http from 'http';
import electronPath from 'electron';
import { Application } from 'spectron';
import executablePath from 'electron';
import { _electron as electron } from 'playwright-core';
import waitForExpect from 'wait-for-expect';
import buildTestBundle, { bundlePath } from './buildTestBundle';
import createMockRNServer from './mockRNServer';
import autoUpdateFeed from '../auto_update.json';

const delay = (time) => new Promise((resolve) => setTimeout(resolve, time));

// eslint-disable-next-line
jasmine.DEFAULT_TIMEOUT_INTERVAL = 6e4;

describe('Application launch', () => {
let app;
let electronApp;
let mainWindow;
const logs = [];

beforeAll(async () => {
await buildTestBundle();
app = new Application({
path: electronPath,
args: ['--user-dir=__e2e__/tmp', 'dist'],
env: {
E2E_TEST: 1,
PACKAGE: 'no',
},
process.env.E2E_TEST = '1';
process.env.PACKAGE = 'no';
electronApp = await electron.launch({
executablePath,
args: ['--user-dir=__e2e__/tmp', './main.js'],
cwd: path.join(__dirname, '../dist'),
});
return app.start();
mainWindow = await electronApp.firstWindow();
mainWindow.on('console', (msg) => logs.push(msg));
await mainWindow.waitForLoadState();
});

afterAll(() => {
if (app && app.isRunning()) {
return app.stop();
}
});

it(`should be v${process.env.npm_package_version}`, async () => {
// Check the App version (dist/package.json) is same with package.json
const { electron } = app;
const version = await electron.remote.app.getVersion();

// Check auto update feed is expected
expect(version).toBe(process.env.npm_package_version);
expect(autoUpdateFeed.url).toBe(
`https://github.com/jhen0409/react-native-debugger/releases/download/v${version}/rn-debugger-macos-universal.zip`,
);
expect(autoUpdateFeed.name).toBe(`v${version}`);
expect(typeof autoUpdateFeed.notes).toBe('string');

console.log(`\nAuto update notes:\n\n${autoUpdateFeed.notes}\n`);
afterAll(async () => {
await electronApp.close();
});

it('should show an initial window', async () => {
const { client, browserWindow } = app;

await client.waitUntilWindowLoaded();
await delay(2000);
const title = await browserWindow.getTitle();
expect(title).toBe(
expect(await mainWindow.title()).toBe(
'React Native Debugger - Attempting reconnection (port 8081)',
);
});
Expand All @@ -75,35 +55,25 @@ describe('Application launch', () => {
let expected = false;
while (attempts > 0 && !expected) {
expected = fs.existsSync(portFile);
await delay(100);
await delay(1000);
attempts--;
}
expect(expected).toBe(true);
});

it("should contain Inspector monitor's component on Redux DevTools", async () => {
const { client } = app;

const el = await client.$('//div[contains(@class, "inspector-")]');
const val = await el.getText();
const val = await mainWindow.textContent('//div[contains(@class, "inspector-")]');
expect(val).not.toBeNull();
});

it('should contain an empty actions list on Redux DevTools', async () => {
const { client } = app;

const el = await client.$('//div[contains(@class, "actionListRows-")]');
const val = await el.getText();
const val = await mainWindow.textContent('//div[contains(@class, "actionListRows-")]');
expect(val).toBe('');
});

it('should show waiting message on React DevTools', async () => {
const { client } = app;
const el = await client.$(
'//h2[text()="Waiting for React to connect…"]',
);
const exist = await el.isExisting();
expect(exist).toBe(true);
const el = await mainWindow.locator('//h2[text()="Waiting for React to connect…"]');
expect(await el.isVisible()).toBe(true);
});

const customRNServerPort = 8098;
Expand All @@ -120,8 +90,7 @@ describe('Application launch', () => {
const url = await getURLFromConnection(wss);
expect(url).toBe('/debugger-proxy?role=debugger&name=Chrome');

const title = await app.browserWindow.getTitle();
expect(title).toBe(
expect(await mainWindow.title()).toBe(
'React Native Debugger - Waiting for client connection (port 8081)',
);
server.close();
Expand Down Expand Up @@ -154,10 +123,11 @@ describe('Application launch', () => {
const url = await getURLFromConnection(wss);
expect(url).toBe('/debugger-proxy?role=debugger&name=Chrome');

const title = await app.browserWindow.getTitle();
expect(title).toBe(
`React Native Debugger - Waiting for client connection (port ${customRNServerPort})`,
);
await waitForExpect(async () => {
expect(await mainWindow.title()).toBe(
`React Native Debugger - Waiting for client connection (port ${customRNServerPort})`,
);
});
server.close();
wss.close();
});
Expand Down Expand Up @@ -213,8 +183,7 @@ describe('Application launch', () => {
);
});
});
const title = await app.browserWindow.getTitle();
expect(title).toBe(
expect(await mainWindow.title()).toBe(
`React Native Debugger - Connected (port ${customRNServerPort})`,
);
});
Expand All @@ -232,26 +201,23 @@ describe('Application launch', () => {
});

it('should have @@INIT action on Redux DevTools', async () => {
const { client } = app;
const el = await client.$('//div[contains(@class, "actionListRows-")]');
const val = await el.getText();
expect(val).toMatch(/@@redux\/INIT/); // Last store is `RemoteDev store instance 1`
expect(
await mainWindow.textContent('//div[contains(@class, "actionListRows-")]')
).toMatch(/@@redux\/INIT/); // Last store is `RemoteDev store instance 1`
});

let currentInstance = 'Autoselect instances'; // Default instance
const wait = () => delay(750);
const selectInstance = async (instance) => {
const { client } = app;
let el = await client.$(`//div[text()="${currentInstance}"]`);
await el.click().then(wait);
await mainWindow.click(`//div[text()="${currentInstance}"]`);
await wait();
currentInstance = instance;
el = await client.$(`//div[text()="${instance}"]`);
return el.click().then(wait);
await mainWindow.click(`//div[text()="${instance}"]`);
await wait();
};
const commit = async () => {
const { client } = app;
const el = await client.$('//div[text()="Commit"]');
await el.click().then(delay(100));
await mainWindow.click('//div[text()="Commit"]');
await wait();
};

const expectActions = {
Expand Down Expand Up @@ -298,11 +264,8 @@ describe('Application launch', () => {
};

const checkInstance = async (name) => {
const { client } = app;

await selectInstance(name);
const el = await client.$('//div[contains(@class, "actionListRows-")]');
const val = await el.getText();
const val = await mainWindow.textContent('//div[contains(@class, "actionListRows-")]');
runExpectActions(name, val);
await commit();
};
Expand All @@ -322,30 +285,25 @@ describe('Application launch', () => {
});

it('should have only specific logs in console of main window', async () => {
const { client } = app;
const logs = await client.getRenderProcessLogs();
// Print renderer process logs
logs.forEach((log) =>
console.log(
`Message: ${log.message}\nSource: ${log.source}\nLevel: ${log.level}`,
`Message: ${log.text()}\nType: ${log.type()}`,
),
);
expect(logs.length).toEqual(1);
const [formDataWarning] = logs;
expect(formDataWarning.source).toBe('worker');
expect(formDataWarning.level).toBe('WARNING');
expect(logs.length).toEqual(3); // clear + clear + warning
const [, , formDataWarning] = logs;
expect(formDataWarning.type()).toBe('warning');
expect(
formDataWarning.message.indexOf(
formDataWarning.text().indexOf(
"Detected you're enabled Network Inspect",
) > 0,
).toBeTruthy();
});

it('should show apollo devtools panel', async () => {
expect(
await app.webContents.executeJavaScript(
'window.__APOLLO_DEVTOOLS_SHOULD_DISPLAY_PANEL__'
),
await mainWindow.evaluate(() => window.__APOLLO_DEVTOOLS_SHOULD_DISPLAY_PANEL__),
).toBeTruthy();
});
});
Expand Down
5 changes: 3 additions & 2 deletions app/containers/App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ipcRenderer, remote } from 'electron';
import { ipcRenderer } from 'electron';
import { getCurrentWindow } from '@electron/remote';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
Expand All @@ -11,7 +12,7 @@ import FormInput from '../components/FormInput';
import Draggable from '../components/Draggable';
import { catchConsoleLogLink } from '../../electron/devtools';

const currentWindow = remote.getCurrentWindow();
const currentWindow = getCurrentWindow();

const styles = {
container: {
Expand Down
5 changes: 3 additions & 2 deletions app/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { findAPortNotInUse } from 'portscanner';
import { webFrame, remote } from 'electron';
import { webFrame } from 'electron';
import { getCurrentWindow } from '@electron/remote';
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
Expand All @@ -13,7 +14,7 @@ import { client, tryADBReverse } from './utils/adb';
import config from './utils/config';
import { toggleOpenInEditor, isOpenInEditorEnabled } from './utils/devtools';

const currentWindow = remote.getCurrentWindow();
const currentWindow = getCurrentWindow();

webFrame.setZoomFactor(1);
webFrame.setVisualZoomLevelLimits(1, 1);
Expand Down
4 changes: 2 additions & 2 deletions app/middlewares/debuggerAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

// Take from https://github.com/facebook/react-native/blob/master/local-cli/server/util/debugger.html

import { remote } from 'electron';
import { getCurrentWindow } from '@electron/remote';
import { bindActionCreators } from 'redux';
import { checkPortStatus } from 'portscanner';
import * as debuggerActions from '../actions/debugger';
Expand All @@ -18,7 +18,7 @@ import { tryADBReverse } from '../utils/adb';
import { clearNetworkLogs, selectRNDebuggerWorkerContext } from '../utils/devtools';
import config from '../utils/config';

const currentWindow = remote.getCurrentWindow();
const currentWindow = getCurrentWindow();
const { SET_DEBUGGER_LOCATION, BEFORE_WINDOW_CLOSE } = debuggerActions;

let worker;
Expand Down
Loading

0 comments on commit 1b04eeb

Please sign in to comment.