diff --git a/spec-main/api-web-contents-spec.ts b/spec-main/api-web-contents-spec.ts index 1a0bb08794fd..35f89fd0dc18 100644 --- a/spec-main/api-web-contents-spec.ts +++ b/spec-main/api-web-contents-spec.ts @@ -3,10 +3,10 @@ import { AddressInfo } from 'net' import * as chaiAsPromised from 'chai-as-promised' import * as path from 'path' import * as http from 'http' -import { BrowserWindow, ipcMain, webContents, session } from 'electron' -import { emittedOnce } from './events-helpers'; -import { closeAllWindows } from './window-helpers'; -import { ifdescribe } from './spec-helpers'; +import { BrowserWindow, ipcMain, webContents, session, clipboard } from 'electron' +import { emittedOnce } from './events-helpers' +import { closeAllWindows } from './window-helpers' +import { ifdescribe, ifit } from './spec-helpers' const { expect } = chai @@ -951,4 +951,58 @@ describe('webContents module', () => { w.loadFile(path.join(fixturesPath, 'pages', 'c.html')) }) }) + + describe('devtools window', () => { + let hasRobotJS = false + try { + // We have other tests that check if native modules work, if we fail to require + // robotjs let's skip this test to avoid false negatives + require('robotjs') + hasRobotJS = true + } catch (err) { /* no-op */ } + + afterEach(closeAllWindows) + + // NB. on macOS, this requires that you grant your terminal the ability to + // control your computer. Open System Preferences > Security & Privacy > + // Privacy > Accessibility and grant your terminal the permission to control + // your computer. + ifit(hasRobotJS)('can receive and handle menu events', async () => { + const w = new BrowserWindow({ show: true, webPreferences: { nodeIntegration: true } }) + w.loadFile(path.join(fixturesPath, 'pages', 'key-events.html')) + + // Ensure the devtools are loaded + w.webContents.closeDevTools() + const opened = emittedOnce(w.webContents, 'devtools-opened') + w.webContents.openDevTools() + await opened + await emittedOnce(w.webContents.devToolsWebContents, 'did-finish-load') + w.webContents.devToolsWebContents.focus() + + // Focus an input field + await w.webContents.devToolsWebContents.executeJavaScript(` + const input = document.createElement('input') + document.body.innerHTML = '' + document.body.appendChild(input) + input.focus() + `) + + // Write something to the clipboard + clipboard.writeText('test value') + + const pasted = w.webContents.devToolsWebContents.executeJavaScript(`new Promise(resolve => { + document.querySelector('input').addEventListener('paste', (e) => { + resolve(e.target.value) + }) + })`) + + // Fake a paste request using robotjs to emulate a REAL keyboard paste event + require('robotjs').keyTap('v', process.platform === 'darwin' ? ['command'] : ['control']) + + const val = await pasted + + // Once we're done expect the paste to have been successful + expect(val).to.equal('test value', 'value should eventually become the pasted value') + }) + }) }) diff --git a/spec/api-web-contents-spec.js b/spec/api-web-contents-spec.js index c2ff63135a8f..8346e0bd7059 100644 --- a/spec/api-web-contents-spec.js +++ b/spec/api-web-contents-spec.js @@ -40,64 +40,6 @@ describe('webContents module', () => { afterEach(() => closeWindow(w).then(() => { w = null })) - describe('devtools window', () => { - let testFn = it - if (process.platform === 'darwin' && isCi) { - testFn = it.skip - } - if (process.platform === 'win32' && isCi) { - testFn = it.skip - } - try { - // We have other tests that check if native modules work, if we fail to require - // robotjs let's skip this test to avoid false negatives - require('robotjs') - } catch (err) { - testFn = it.skip - } - - testFn('can receive and handle menu events', async function () { - this.timeout(5000) - w.show() - w.loadFile(path.join(fixtures, 'pages', 'key-events.html')) - // Ensure the devtools are loaded - w.webContents.closeDevTools() - const opened = emittedOnce(w.webContents, 'devtools-opened') - w.webContents.openDevTools() - await opened - await emittedOnce(w.webContents.devToolsWebContents, 'did-finish-load') - w.webContents.devToolsWebContents.focus() - - // Focus an input field - await w.webContents.devToolsWebContents.executeJavaScript( - `const input = document.createElement('input'); - document.body.innerHTML = ''; - document.body.appendChild(input) - input.focus();` - ) - - // Write something to the clipboard - clipboard.writeText('test value') - - // Fake a paste request using robotjs to emulate a REAL keyboard paste event - require('robotjs').keyTap('v', process.platform === 'darwin' ? ['command'] : ['control']) - - const start = Date.now() - let val - - // Check every now and again for the pasted value (paste is async) - while (val !== 'test value' && Date.now() - start <= 1000) { - val = await w.webContents.devToolsWebContents.executeJavaScript( - `document.querySelector('input').value` - ) - await new Promise(resolve => setTimeout(resolve, 10)) - } - - // Once we're done expect the paste to have been successful - expect(val).to.equal('test value', 'value should eventually become the pasted value') - }) - }) - describe('webrtc ip policy api', () => { it('can set and get webrtc ip policies', () => { const policies = [