Skip to content

Commit 9c6fc71

Browse files
authored
Merge branch 'master' into patch-1
2 parents b9bb37c + 640b23a commit 9c6fc71

File tree

20 files changed

+8902
-1799
lines changed

20 files changed

+8902
-1799
lines changed

README.md

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
[![CI](https://github.com/electron-userland/spectron/workflows/CI/badge.svg)](https://github.com/electron-userland/spectron/actions) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/)
44
[![dependencies](https://img.shields.io/david/electron/spectron.svg)](https://david-dm.org/electron/spectron) [![license:mit](https://img.shields.io/badge/license-mit-blue.svg)](https://opensource.org/licenses/MIT) [![npm:](https://img.shields.io/npm/v/spectron.svg)](https://www.npmjs.com/package/spectron) [![downloads](https://img.shields.io/npm/dm/spectron.svg)](https://www.npmjs.com/package/spectron)
55

6+
### 🚨 On February 1, 2022, Spectron will be officially deprecated by the Electron team. Please read about more about [our planned deprecation here](https://github.com/electron-userland/spectron/issues/1045).
7+
68
Easily test your [Electron](http://electron.atom.io) apps using
7-
[ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver) and
9+
[ChromeDriver](https://sites.google.com/chromium.org/driver) and
810
[WebdriverIO](http://webdriver.io).
911

1012
## Version Map
@@ -34,6 +36,8 @@ For given versions of Electron you must depend on a very specific version range
3436
| `^11.0.0` | `^13.0.0`|
3537
| `^12.0.0` | `^14.0.0`|
3638
| `^13.0.0` | `^15.0.0`|
39+
| `^14.0.0` | `^16.0.0`|
40+
| `^15.0.0` | `^17.0.0`|
3741

3842
Learn more from [this presentation](https://speakerdeck.com/kevinsawicki/testing-your-electron-apps-with-chromedriver).
3943

@@ -133,6 +137,13 @@ For more information on how to configure mocha, please visit [mocha](https://moc
133137

134138
As stated in [issue #19](https://github.com/electron/spectron/issues/19), Spectron will not be able to start if your Electron app is launched using the `remote-debugging-port` command-line switch (i.e. `app.commandLine.appendSwitch('remote-debugging-port', <debugging-port-number>);`). Please make sure to include the necessary logic in your app's code to disable the switch during tests.
135139

140+
As mentioned in [issue #202](https://github.com/electron-userland/spectron/issues/202#issuecomment-632223955),
141+
`app.start()` promise won't resolve if the electron application calls
142+
`setPath('userData', path)`. Webdriver places a port file into the `userData`
143+
directory and needs to know where to look for it. The workaround is to pass
144+
`chromeDriverArgs: ['user-data-dir=/custom/userData/path']` to the `Application`
145+
constructor.
146+
136147
## Application API
137148

138149
Spectron exports an `Application` class that when configured, can start and
@@ -150,7 +161,7 @@ Create a new application with the following options:
150161
array.
151162
* `args` - Array of arguments to pass to the Electron application.
152163
* `chromeDriverArgs` - Array of arguments to pass to ChromeDriver.
153-
See [here](https://sites.google.com/a/chromium.org/chromedriver/capabilities) for details on the Chrome arguments.
164+
See [here](https://sites.google.com/chromium.org/driver/capabilities) for details on the Chrome arguments.
154165
* `cwd`- String path to the working directory to use for the launched
155166
application. Defaults to `process.cwd()`.
156167
* `env` - Object of additional environment variables to set in the launched
@@ -208,7 +219,7 @@ property which do not require Node integration.
208219

209220
#### client
210221

211-
Spectron uses [WebdriverIO](http://webdriver.io) and exposes the managed
222+
Spectron uses [WebdriverIO](https://webdriver.io) and exposes the managed
212223
`client` property on the created `Application` instances.
213224

214225
The `client` API is WebdriverIO's `browser` object. Documentation can be found
@@ -221,8 +232,10 @@ All the commands return a `Promise`.
221232
So if you wanted to get the text of an element you would do:
222233

223234
```js
224-
app.client.getText('#error-alert').then(function (errorText) {
225-
console.log('The #error-alert text content is ' + errorText)
235+
app.client.$('#error-alert').then(function (element) {
236+
element.getText().then(function (errorText) {
237+
console.log('The #error-alert text content is ' + errorText)
238+
})
226239
})
227240
```
228241

@@ -239,9 +252,8 @@ API in your tests you would do:
239252

240253
```js
241254
app.electron.clipboard.writeText('pasta')
242-
.electron.clipboard.readText().then(function (clipboardText) {
243-
console.log('The clipboard text is ' + clipboardText)
244-
})
255+
const clipboardText = app.electron.clipboard.readText()
256+
console.log('The clipboard text is ' + clipboardText)
245257
```
246258

247259
#### browserWindow
@@ -651,7 +663,7 @@ test.afterEach(t => {
651663
return t.context.app.stop();
652664
});
653665
654-
test(t => {
666+
test('opens a window', t => {
655667
return t.context.app.client.waitUntilWindowLoaded()
656668
.getWindowCount().then(count => {
657669
t.is(count, 1);
@@ -688,7 +700,7 @@ test.afterEach.always(async t => {
688700
await t.context.app.stop();
689701
});
690702
691-
test(async t => {
703+
test('example', async t => {
692704
const app = t.context.app;
693705
await app.client.waitUntilWindowLoaded();
694706

lib/api.js

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Api.prototype.loadApi = function () {
7979
);
8080
}
8181
const electron = window[requireName]('electron');
82+
electron.remote = window[requireName]('@electron/remote');
8283
const process = window[requireName]('process');
8384

8485
const api = {
@@ -350,9 +351,8 @@ Api.prototype.addCapturePageSupport = function () {
350351
async function (rect, requireName, done) {
351352
const args = [];
352353
if (rect != null) args.push(rect);
353-
const browserWindow = window[requireName](
354-
'electron'
355-
).remote.getCurrentWindow();
354+
const browserWindow =
355+
window[requireName]('@electron/remote').getCurrentWindow();
356356
const image = await browserWindow.capturePage.apply(
357357
browserWindow,
358358
args
@@ -413,9 +413,8 @@ Api.prototype.addSavePageSupport = function () {
413413
app.client.addCommand('webContents.savePage', function (fullPath, saveType) {
414414
return this.executeAsync(
415415
async function (fullPath, saveType, requireName, done) {
416-
const webContents = window[requireName](
417-
'electron'
418-
).remote.getCurrentWebContents();
416+
const webContents =
417+
window[requireName]('@electron/remote').getCurrentWebContents();
419418
await webContents.savePage(fullPath, saveType);
420419
done();
421420
},
@@ -445,9 +444,8 @@ Api.prototype.addExecuteJavaScriptSupport = function () {
445444
function (code, useGesture) {
446445
return this.executeAsync(
447446
async function (code, useGesture, requireName, done) {
448-
const webContents = window[requireName](
449-
'electron'
450-
).remote.getCurrentWebContents();
447+
const webContents =
448+
window[requireName]('@electron/remote').getCurrentWebContents();
451449
const result = await webContents.executeJavaScript(code, useGesture);
452450
done(result);
453451
},
@@ -538,7 +536,7 @@ function callRenderApi(moduleName, api, args, requireName) {
538536
}
539537

540538
function callMainApi(moduleName, api, args, requireName) {
541-
let module = window[requireName]('electron').remote;
539+
let module = window[requireName]('@electron/remote');
542540
if (moduleName) {
543541
module = module[moduleName];
544542
}
@@ -550,16 +548,14 @@ function callMainApi(moduleName, api, args, requireName) {
550548
}
551549

552550
function callWebContentsApi(name, args, requireName) {
553-
const webContents = window[requireName](
554-
'electron'
555-
).remote.getCurrentWebContents();
551+
const webContents =
552+
window[requireName]('@electron/remote').getCurrentWebContents();
556553
return webContents[name].apply(webContents, args);
557554
}
558555

559556
function callBrowserWindowApi(name, args, requireName) {
560-
const browserWindow = window[requireName](
561-
'electron'
562-
).remote.getCurrentWindow();
557+
const browserWindow =
558+
window[requireName]('@electron/remote').getCurrentWindow();
563559
return browserWindow[name].apply(browserWindow, args);
564560
}
565561

lib/spectron.d.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,7 @@ declare module 'spectron' {
6363
}[];
6464
}
6565

66-
export interface SpectronClient extends WebdriverIO.BrowserObject {
67-
/**
68-
* Focus a window using its title or URL.
69-
* <webview> tags can also be focused as a separate window.
70-
*/
71-
switchWindow(urlOrTitleToMatch: string): Promise<void>;
72-
66+
export interface SpectronClient extends WebdriverIO.Browser<'async'> {
7367
/**
7468
* Wait until the window is no longer loading.
7569
* Takes an optional timeout in milliseconds that defaults to 5000.
@@ -118,15 +112,19 @@ declare module 'spectron' {
118112
): Promise<AccessibilityAuditResult>;
119113
}
120114

121-
export interface SpectronWindow extends Electron.BrowserWindow {
122-
capturePage(): Promise<Electron.NativeImage>;
123-
}
115+
export type SpectronWindow = {
116+
[P in keyof Electron.BrowserWindow]: Electron.BrowserWindow[P] extends (
117+
...args: infer A
118+
) => infer R
119+
? (...args: A) => Promise<R>
120+
: undefined;
121+
};
124122

125123
export interface SpectronWebContents extends Electron.WebContents {
126124
savePage(
127125
fullPath: string,
128126
saveType: 'HTMLOnly' | 'HTMLComplete' | 'MHTML',
129-
callback?: (eror: Error) => void
127+
callback?: (error: Error) => void
130128
): boolean;
131129
savePage(
132130
fullPath: string,
@@ -191,7 +189,7 @@ declare module 'spectron' {
191189
args?: string[];
192190
/**
193191
* Array of arguments to pass to ChromeDriver.
194-
* See here (https://sites.google.com/a/chromium.org/chromedriver/capabilities) for details
192+
* See here (https://sites.google.com/chromium.org/driver/capabilities) for details
195193
* on the Chrome arguments.
196194
*/
197195
chromeDriverArgs?: string[];
@@ -257,7 +255,7 @@ declare module 'spectron' {
257255
* Each Electron module is exposed as a property on the electron property so you can
258256
* think of it as an alias for require('electron') from within your app.
259257
*/
260-
electron: Electron.RemoteMainInterface;
258+
electron: typeof Electron;
261259
/**
262260
* The browserWindow property is an alias for require('electron').remote.getCurrentWindow().
263261
* It provides you access to the current BrowserWindow and contains all the APIs.

0 commit comments

Comments
 (0)