Skip to content

Commit

Permalink
feat(plugin): add support for Electron
Browse files Browse the repository at this point in the history
To make the plugin work with Electron, you just need to set the `remote-debugging-port` option when you launch Cypress as follows:

```bash
$ ELECTRON_EXTRA_LAUNCH_ARGS=--remote-debugging-port=9222 cypress run --browser electron
```

Please refer to the [Electron documentation](https://www.electronjs.org/docs/latest/api/command-line-switches#--remote-debugging-portport) and the [Cypress documentation](https://docs.cypress.io/api/plugins/browser-launch-api#Modify-Electron-app-switches) for more information on how to properly configure this switch.

closes #46
  • Loading branch information
derevnjuk committed Jan 15, 2023
1 parent a318704 commit 7983043
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 24 deletions.
18 changes: 12 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,22 @@ You can also specify a different destination folder for the generated HAR file b
Alternatively, you can pass the `hars_folders` variable in the CLI using the `--env` option:

```bash
cypress run --browser chrome --env hars_folders=cypress/hars
$ cypress run --browser chrome --env hars_folders=cypress/hars
```

Finally, to start running your tests, use the following command:

```bash
cypress run --browser chrome
$ cypress run --browser chrome
```

> ✴ Currently, only Chrome family browsers are supported.
> 🚧 Currently, only Chrome family browsers are supported. But this plugin also works with Electron, you just need to set the remote-debugging-port option when you launch Cypress as follows:
>
> ```bash
> ELECTRON_EXTRA_LAUNCH_ARGS=--remote-debugging-port=9222 cypress run --browser electron
> ```
>
> Please refer to the [Electron documentation](https://www.electronjs.org/docs/latest/api/command-line-switches#--remote-debugging-portport) and the [Cypress documentation](https://docs.cypress.io/api/plugins/browser-launch-api#Modify-Electron-app-switches) for more information on how to properly configure this switch.
## Commands
Expand Down Expand Up @@ -182,15 +188,15 @@ For example, to only include requests that have a status code of 400 or greater,
cy.recordHar({ minStatusCodeToInclude: 400 });
```
> As of version 6, this option will be removed. Use `excludeStatusCodes` instead.
> As of version 6, this option will be removed. Use `excludeStatusCodes` instead.
Alternatively, you can have more granular control over the requests to exclude by passing an array of status codes you want to exclude from the recorded HAR file.
```js
cy.recordHar({ excludeStatusCodes: [200, 201, 204] });
```
> Please note that both options `minStatusCodeToInclude` and `excludeStatusCodes` are mutually exclusive.
> Please note that both options `minStatusCodeToInclude` and `excludeStatusCodes` are mutually exclusive.
By default, when you use `recordHar` command, it will include the blob requests in the recorded HAR file. However, those requests only make sense when they are used on the same page they were created. To exclude the blob requests from the recorded HAR file, set the `includeBlobs` to false as follows:
Expand Down Expand Up @@ -309,7 +315,7 @@ module.exports = defineConfig({
});
```
> Please note, to utilize this experimental mechanism for setting up lifecycle, you must either disable the interactive mode or enable the "experimentalInteractiveRunEvents" feature. For more details, see the documentation: https://docs.cypress.io/guides/references/experiments#Configuration
> Please note, to utilize this experimental mechanism for setting up lifecycle, you must either disable the interactive mode or enable the "experimentalInteractiveRunEvents" feature. For more details, see the documentation: https://docs.cypress.io/guides/references/experiments#Configuration
## License
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"keywords": [
"cypress",
"har",
"electron",
"cypress-plugin",
"chrome",
"http-archive",
Expand Down
45 changes: 45 additions & 0 deletions src/Plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
match,
mock,
reset,
spy,
verify,
when
} from 'ts-mockito';
Expand Down Expand Up @@ -99,11 +100,21 @@ describe('Plugin', () => {
const connectionFactoryMock = mock<ConnectionFactory>();
const connectionMock = mock<Connection>();
const writableStreamMock = mock<WriteStream>();
const processEnv = process.env;

let plugin!: Plugin;
let processSpy!: NodeJS.Process;

beforeEach(() => {
processSpy = spy(process);

when(processSpy.env).thenReturn({
...processEnv,
ELECTRON_EXTRA_LAUNCH_ARGS: ''
});

useFakeTimers();

plugin = new Plugin(
instance(loggerMock),
instance(fileManagerMock),
Expand All @@ -115,6 +126,7 @@ describe('Plugin', () => {
afterEach(() => {
jest.useRealTimers();
reset<
| NodeJS.Process
| Logger
| FileManager
| Connection
Expand All @@ -123,6 +135,7 @@ describe('Plugin', () => {
| ObserverFactory
| Observer<NetworkRequest>
>(
processSpy,
loggerMock,
fileManagerMock,
connectionMock,
Expand Down Expand Up @@ -173,6 +186,38 @@ describe('Plugin', () => {
`An unsupported browser family was used: ${browser.name}`
);
});

it('should throw an error when Electron is used and switches are missed', () => {
// arrange
const browser = {
family: 'chromium',
name: 'electron'
} as Cypress.Browser;
const args: string[] = [];
// act
const act = () => plugin.ensureBrowserFlags(browser, args);
// assert
expect(act).toThrowError(
`Missing '--remote-debugging-port' command line switch for Electron browser`
);
});

it('should extract --remote-debugging-port from ELECTRON_EXTRA_LAUNCH_ARGS env variable', () => {
// arrange
const browser = {
family: 'chromium',
name: 'electron'
} as Cypress.Browser;
const args: string[] = [];
when(processSpy.env).thenReturn({
...processEnv,
ELECTRON_EXTRA_LAUNCH_ARGS: '--remote-debugging-port=9090'
});
// act
const result = plugin.ensureBrowserFlags(browser, args);
// assert
expect(result).toEqual([]);
});
});

describe('saveHar', () => {
Expand Down
50 changes: 32 additions & 18 deletions src/Plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { Connection, ConnectionFactory, RetryStrategy } from './cdp';
import {
EntryBuilder,
HarBuilder,
NetworkIdleMonitor,
NetworkObserverOptions,
NetworkRequest,
Observer,
NetworkObserverOptions,
ObserverFactory,
NetworkIdleMonitor
ObserverFactory
} from './network';
import { join } from 'path';
import { WriteStream } from 'fs';
Expand Down Expand Up @@ -61,11 +61,17 @@ export class Plugin {
);
}

const browserFlags: string[] = this.ensureRdpAddrArgs(
this.ensureTestingFlags(args)
);
const electronUsed = browser.name === 'electron';

if (electronUsed) {
args = this.parseElectronSwitches(browser);
}

return browserFlags.filter((x: string): boolean => !args.includes(x));
const browserFlags: string[] = this.ensureRdpAddrArgs(args);

return electronUsed
? []
: browserFlags.filter((x: string): boolean => !args.includes(x));
}

public async recordHar(options: RecordOptions): Promise<void> {
Expand Down Expand Up @@ -130,6 +136,25 @@ export class Plugin {
return null;
}

private parseElectronSwitches(browser: Cypress.Browser): string[] {
if (
!process.env.ELECTRON_EXTRA_LAUNCH_ARGS?.includes(this.PORT_OPTION_NAME)
) {
this.logger
.err(`The '${browser.name}' browser was detected, however, the required '${this.PORT_OPTION_NAME}' command line switch was not provided.
This switch is necessary to enable remote debugging over HTTP on the specified port.
Please refer to the documentation:
- https://www.electronjs.org/docs/latest/api/command-line-switches#--remote-debugging-portport
- https://docs.cypress.io/api/plugins/browser-launch-api#Modify-Electron-app-switches`);
throw new Error(
`Missing '${this.PORT_OPTION_NAME}' command line switch for Electron browser`
);
}

return process.env.ELECTRON_EXTRA_LAUNCH_ARGS.split(' ');
}

private async buildHar(): Promise<string | undefined> {
if (this.tmpPath) {
const content = await this.fileManager.readFile(this.tmpPath);
Expand Down Expand Up @@ -187,17 +212,6 @@ export class Plugin {
return ['chromium'].includes(browser?.family);
}

private ensureTestingFlags(args: string[]): string[] {
return [
...args,
'--no-sandbox',
'--disable-background-networking',
'--reduce-security-for-testing',
'--allow-insecure-localhost',
'--ignore-certificate-errors'
];
}

private ensureRdpAddrArgs(args: string[]): string[] {
const {
host = 'localhost',
Expand Down

0 comments on commit 7983043

Please sign in to comment.