Skip to content

Commit

Permalink
Merge branch 'master' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
VerteDinde committed Feb 2, 2022
2 parents b9bb37c + 640b23a commit 9c6fc71
Show file tree
Hide file tree
Showing 20 changed files with 8,902 additions and 1,799 deletions.
32 changes: 22 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
[![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/)
[![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)

### 🚨 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).

Easily test your [Electron](http://electron.atom.io) apps using
[ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver) and
[ChromeDriver](https://sites.google.com/chromium.org/driver) and
[WebdriverIO](http://webdriver.io).

## Version Map
Expand Down Expand Up @@ -34,6 +36,8 @@ For given versions of Electron you must depend on a very specific version range
| `^11.0.0` | `^13.0.0`|
| `^12.0.0` | `^14.0.0`|
| `^13.0.0` | `^15.0.0`|
| `^14.0.0` | `^16.0.0`|
| `^15.0.0` | `^17.0.0`|

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

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

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.

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

## Application API

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

#### client

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

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

```js
app.client.getText('#error-alert').then(function (errorText) {
console.log('The #error-alert text content is ' + errorText)
app.client.$('#error-alert').then(function (element) {
element.getText().then(function (errorText) {
console.log('The #error-alert text content is ' + errorText)
})
})
```

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

```js
app.electron.clipboard.writeText('pasta')
.electron.clipboard.readText().then(function (clipboardText) {
console.log('The clipboard text is ' + clipboardText)
})
const clipboardText = app.electron.clipboard.readText()
console.log('The clipboard text is ' + clipboardText)
```

#### browserWindow
Expand Down Expand Up @@ -651,7 +663,7 @@ test.afterEach(t => {
return t.context.app.stop();
});

test(t => {
test('opens a window', t => {
return t.context.app.client.waitUntilWindowLoaded()
.getWindowCount().then(count => {
t.is(count, 1);
Expand Down Expand Up @@ -688,7 +700,7 @@ test.afterEach.always(async t => {
await t.context.app.stop();
});

test(async t => {
test('example', async t => {
const app = t.context.app;
await app.client.waitUntilWindowLoaded();

Expand Down
28 changes: 12 additions & 16 deletions lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Api.prototype.loadApi = function () {
);
}
const electron = window[requireName]('electron');
electron.remote = window[requireName]('@electron/remote');
const process = window[requireName]('process');

const api = {
Expand Down Expand Up @@ -350,9 +351,8 @@ Api.prototype.addCapturePageSupport = function () {
async function (rect, requireName, done) {
const args = [];
if (rect != null) args.push(rect);
const browserWindow = window[requireName](
'electron'
).remote.getCurrentWindow();
const browserWindow =
window[requireName]('@electron/remote').getCurrentWindow();
const image = await browserWindow.capturePage.apply(
browserWindow,
args
Expand Down Expand Up @@ -413,9 +413,8 @@ Api.prototype.addSavePageSupport = function () {
app.client.addCommand('webContents.savePage', function (fullPath, saveType) {
return this.executeAsync(
async function (fullPath, saveType, requireName, done) {
const webContents = window[requireName](
'electron'
).remote.getCurrentWebContents();
const webContents =
window[requireName]('@electron/remote').getCurrentWebContents();
await webContents.savePage(fullPath, saveType);
done();
},
Expand Down Expand Up @@ -445,9 +444,8 @@ Api.prototype.addExecuteJavaScriptSupport = function () {
function (code, useGesture) {
return this.executeAsync(
async function (code, useGesture, requireName, done) {
const webContents = window[requireName](
'electron'
).remote.getCurrentWebContents();
const webContents =
window[requireName]('@electron/remote').getCurrentWebContents();
const result = await webContents.executeJavaScript(code, useGesture);
done(result);
},
Expand Down Expand Up @@ -538,7 +536,7 @@ function callRenderApi(moduleName, api, args, requireName) {
}

function callMainApi(moduleName, api, args, requireName) {
let module = window[requireName]('electron').remote;
let module = window[requireName]('@electron/remote');
if (moduleName) {
module = module[moduleName];
}
Expand All @@ -550,16 +548,14 @@ function callMainApi(moduleName, api, args, requireName) {
}

function callWebContentsApi(name, args, requireName) {
const webContents = window[requireName](
'electron'
).remote.getCurrentWebContents();
const webContents =
window[requireName]('@electron/remote').getCurrentWebContents();
return webContents[name].apply(webContents, args);
}

function callBrowserWindowApi(name, args, requireName) {
const browserWindow = window[requireName](
'electron'
).remote.getCurrentWindow();
const browserWindow =
window[requireName]('@electron/remote').getCurrentWindow();
return browserWindow[name].apply(browserWindow, args);
}

Expand Down
24 changes: 11 additions & 13 deletions lib/spectron.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,7 @@ declare module 'spectron' {
}[];
}

export interface SpectronClient extends WebdriverIO.BrowserObject {
/**
* Focus a window using its title or URL.
* <webview> tags can also be focused as a separate window.
*/
switchWindow(urlOrTitleToMatch: string): Promise<void>;

export interface SpectronClient extends WebdriverIO.Browser<'async'> {
/**
* Wait until the window is no longer loading.
* Takes an optional timeout in milliseconds that defaults to 5000.
Expand Down Expand Up @@ -118,15 +112,19 @@ declare module 'spectron' {
): Promise<AccessibilityAuditResult>;
}

export interface SpectronWindow extends Electron.BrowserWindow {
capturePage(): Promise<Electron.NativeImage>;
}
export type SpectronWindow = {
[P in keyof Electron.BrowserWindow]: Electron.BrowserWindow[P] extends (
...args: infer A
) => infer R
? (...args: A) => Promise<R>
: undefined;
};

export interface SpectronWebContents extends Electron.WebContents {
savePage(
fullPath: string,
saveType: 'HTMLOnly' | 'HTMLComplete' | 'MHTML',
callback?: (eror: Error) => void
callback?: (error: Error) => void
): boolean;
savePage(
fullPath: string,
Expand Down Expand Up @@ -191,7 +189,7 @@ declare module 'spectron' {
args?: string[];
/**
* Array of arguments to pass to ChromeDriver.
* See here (https://sites.google.com/a/chromium.org/chromedriver/capabilities) for details
* See here (https://sites.google.com/chromium.org/driver/capabilities) for details
* on the Chrome arguments.
*/
chromeDriverArgs?: string[];
Expand Down Expand Up @@ -257,7 +255,7 @@ declare module 'spectron' {
* Each Electron module is exposed as a property on the electron property so you can
* think of it as an alias for require('electron') from within your app.
*/
electron: Electron.RemoteMainInterface;
electron: typeof Electron;
/**
* The browserWindow property is an alias for require('electron').remote.getCurrentWindow().
* It provides you access to the current BrowserWindow and contains all the APIs.
Expand Down
Loading

0 comments on commit 9c6fc71

Please sign in to comment.