{"id":28893614,"url":"https://github.com/devexpress/testcafe-browser-provider-electron","last_synced_at":"2025-07-14T09:02:50.076Z","repository":{"id":45537039,"uuid":"93629601","full_name":"DevExpress/testcafe-browser-provider-electron","owner":"DevExpress","description":"This is the Electron browser provider plugin for TestCafe.","archived":false,"fork":false,"pushed_at":"2024-08-27T10:03:17.000Z","size":1451,"stargazers_count":48,"open_issues_count":3,"forks_count":30,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-06-13T03:48:02.842Z","etag":null,"topics":["e2e-tests","electron","nodejs","testcafe","testcafe-browser-provider"],"latest_commit_sha":null,"homepage":"https://testcafe.io","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DevExpress.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-07T11:49:24.000Z","updated_at":"2024-10-19T10:00:44.000Z","dependencies_parsed_at":"2024-01-15T11:51:11.054Z","dependency_job_id":"4bdbceaf-3049-4edc-acf5-fff04acc54fd","html_url":"https://github.com/DevExpress/testcafe-browser-provider-electron","commit_stats":{"total_commits":68,"total_committers":18,"mean_commits":"3.7777777777777777","dds":0.6029411764705883,"last_synced_commit":"d23e8df46077bd4e07ba60f9af766c468a1fd72c"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/DevExpress/testcafe-browser-provider-electron","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevExpress%2Ftestcafe-browser-provider-electron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevExpress%2Ftestcafe-browser-provider-electron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevExpress%2Ftestcafe-browser-provider-electron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevExpress%2Ftestcafe-browser-provider-electron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DevExpress","download_url":"https://codeload.github.com/DevExpress/testcafe-browser-provider-electron/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevExpress%2Ftestcafe-browser-provider-electron/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261055312,"owners_count":23103224,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["e2e-tests","electron","nodejs","testcafe","testcafe-browser-provider"],"created_at":"2025-06-21T03:08:06.149Z","updated_at":"2025-07-14T09:02:50.065Z","avatar_url":"https://github.com/DevExpress.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# testcafe-browser-provider-electron\n[![Build Status](https://travis-ci.org/DevExpress/testcafe-browser-provider-electron.svg)](https://travis-ci.org/DevExpress/testcafe-browser-provider-electron)\n\nUse this plugin to test **Electron** applications with [TestCafe](http://devexpress.github.io/testcafe).\n\n## Getting Started\n\n### Installation\n\n```sh\nnpm install testcafe-browser-provider-electron\n```\n\n### Testing a JavaScript Application\n\nIf your JavaScript application runs in Electron, follow these steps to set up testing.\n\n1. Create a JSON `.testcafe-electron-rc.json` or JavaScript `.testcafe-electron-rc.js` [configuration file](#configuration) in the root application directory. Include the following settings to this file.\n\n    *JSON*\n\n    ```json\n    {\n        \"mainWindowUrl\": \"./index.html\"\n    }\n    ```\n\n    *JavaScript*\n\n    ```js\n    module.exports = {\n        mainWindowUrl: './index.html'\n    }\n    ```\n\n    An Electron app has a file that is loaded as a startup page. TestCafe waits until Electron loads this page and then runs tests. Specify the path to this file with `mainWindowUrl` option. If a relative path is specified, it is resolved from the configuration file location.\n\n    For information about other options, see the [Configuration](#configuration) section.\n\n2. Install the Electron module of the required version.\n\n    ```sh\n    npm install electron@latest\n    ```\n\n    The command above installs the latest version of the Electron executable.\n\n3. Define the path to the config file. Use browser provider postfix: `electron:\u003cpath_to_testcafe-electron-rc_directory\u003e`. Then run tests.\n\n    ```sh\n    testcafe \"electron:/home/user/electron-app\" \"\u003ctests_directory\u003e/**/*.js\"\n    ```\n\n4. The configuration file might be not in the application root directory. In that case specify the path to the configuration file like this:\n\n    ```json\n    {\n      \"mainWindowUrl\": \"./index.html\",\n      \"appPath\":       \"/home/user/my_app\"  \n    }\n    ```\n\n    In this instance, the `appPath` directory will be used as a working directory of the Electron application.\n\n### Testing an Executable Electron Application\n\nIf your Electron app is built it has `\u003cyour_app_name\u003e.exe` or `electron.exe` file. In that case you don't need an Electron module to run tests. Perform the following steps instead.\n\n1. In the application directory, create a configuration file with the following settings.\n\n    ```json\n    {\n        \"mainWindowUrl\": \"./index.html\",\n        \"electronPath\":  \"/home/user/myElectronApp/electron\"\n    }\n    ```\n\n    `mainWindowUrl` points to the application startup page; `electronPath` defines the path to your application's executable file. If you specify relative paths, they will be resolved from the configuration file location.\n\n2. When you run tests, define the path to the configuration file. To do so, add the browser provider postfix: `electron:\u003cpath_to_testcafe-electron-rc_directory\u003e`.\n\n    ```sh\n    testcafe \"electron:/home/user/electron-app\" \"\u003ctests_directory\u003e/**/*.js\"\n    ```\n\n### Launching Tests from API\n\nTo launch tests through the API, specify the application path with `electron:` prefix and pass it to the `browsers` method.\n\n```js\ntestCafe\n    .createRunner()\n    .src('path/to/test/file.js')\n    .browsers('electron:/home/user/electron-app')\n    .run();\n```\n\n### Specifying Target Webpage in Test Code\n\nIn most cases, the target webpage is the main application page specified via the `mainWindowUrl` configuration option.\n\n```json\n{\n  \"mainWindowUrl\": \"./index.html\"\n}\n```\n\n```js\nfixture `Electron test`\n    .page('./index.html');\n```\n\nHowever, you can specify any application page if your app contains more than one.\n\n```js\nfixture `Electron test`\n    .page('./views/detail.html');\n```\n\n## Configuration\n\nYou can specify browser provider options in a JSON `.testcafe-electron-rc.json` or JavaScript `.testcafe-electron-rc.js` configuration file.\n\n*JSON*\n\n```json\n{\n    \"mainWindowUrl\": \"./index.html\",\n    \"appArgs\": [\"--arg1\", \"--arg2\"],\n    \"enableNavigateEvents\": true\n}\n```\n\n*JavaScript*\n\n```js\nmodule.exports = {\n    mainWindowUrl: './index.html',\n    appArgs: ['--arg1', '--arg2'],\n    enableNavigateEvents: true\n}\n```\n\nThe `.js` file must export an object with the configuration settings.\n\nUse JavaScript if you need additional flexibility. For instance, you can specify settings that depend on a condition.\n\nThe browser provider supports the following options:\n\n### mainWindowUrl\n\n__Required.__ Specifies the URL of the application's main window page.\nFor local application pages, you can also specify a relative (to the application directory) or an absolute path to the file of the page.\n\n### appPath\n\n__Optional.__ Alters path to the application, which, by default, must be located at the [default Electron app directory](https://github.com/electron/electron/blob/master/docs/tutorial/application-distribution.md#application-distribution).\nYou can use the `appPath` option to override the default path by specifying a new absolute path. Alternatively, you can append a relative path to the path specified after the \"electron:\" prefix.\n\n### appArgs\n\n__Optional.__ Overrides application command line arguments with the values specified in this option. It should be an array or an object with numeric keys.\n\n### electronPath\n\n__Optional__. Specifies a path to the electron binary. If `electronPath` is not specified, the [electron package](https://www.npmjs.com/package/electron) should be installed.\nOn macOS, it can be either a path to the `electron` binary, or a path to the entire Electron.app (e.g. `/Applications/Electron.app`). It may be necessary to stop all other running\ninstances of the specified Electron binary.\n\n### enableNavigateEvents\n\n__Optional.__ `testcafe-browser-provider-electron` suppresses `did-navigate` and `will-navigate`  webContent events because you will be unable to run tests if these events are used to prevent navigation. You can enable them back by setting this option to `true`.\n\n### openDevTools\n\n__Optional.__ If `true`, DevTools will be opened just before tests start.\n\n## Helpers\n\nYou can use helper functions from the provider in your test files. Use ES6 import statement to access them.\n\n```js\nimport { getMainMenu, clickOnMenuItem } from 'testcafe-browser-provider-electron';\n```\n\n### getMainMenuItem\n\nGets a snapshot of the specified application's main menu item.\n\n```js\nasync function getMainMenuItem (menuItemSelector)\n```\n\nParameter          | Type   | Description\n------------------ | ------ | -----\n`menuItemSelector` | String | An array of menu item labels and/or objects with properties \"label\" and \"index\".\n\nFor example, you can pass the following values in the `menuItemSelector` parameter.\n\n* `['File', 'Open']`\n* `['File', { label: 'Open' }]`\n* `Context Menu \u003e Undo`\n\nIf there are several menu items with the same label on the same level, you can specify a one-based \"index\"\nproperty:\n\n* `['Window', {label: 'My Window', index: 2}]`\n\nThis value corresponds to the second menu item with label `My Window` in the `Window` menu.\n\nCheck the properties available in the snapshot\n[here](https://github.com/electron/electron/blob/master/docs/api/menu-item.md).\n\n**Example**\n\n```js\nimport { getMainMenuItem } from 'testcafe-browser-provider-electron';\n\nfixture `Electron test`\n    .page('./index.html');\n\ntest('Check the menu item role', async t =\u003e {\n    const menuItem = await getMainMenuItem(['Main Menu', 'Edit', 'Undo']);\n\n    await t.expect(menuItem.role).eql('undo');\n});\n```\n\n### getContextMenuItem\n\nGets a snapshot of the specified menu item from the **most recently** opened context menu.\n\n```js\nasync function getContextMenuItem (menuItemSelector)\n```\n\nParameter          | Type   | Description\n------------------ | ------ | -----\n`menuItemSelector` | String | An array of menu item labels and/or objects with properties \"label\" and \"index\".\n\nFor example, you can pass the following values in the `menuItemSelector` parameter.\n\n* `['Go To', 'Declaration']`\n* `['Go To', { label: 'Declaration' }]`\n\nIf there are several menu items with the same label on the same level, you can specify a one-based \"index\"\nproperty:\n\n* `['Go To', {label: 'My Function', index: 2}]`\n\nThis value corresponds to the second menu item with label `My Function` in the `Go To` submenu.\n\nCheck the properties available in the snapshot\n[here](https://github.com/electron/electron/blob/master/docs/api/menu-item.md).\n\n**Example**\n\n```js\nimport { getContextMenuItem } from 'testcafe-browser-provider-electron';\n\nfixture `Electron test`\n    .page('./index.html');\n\ntest('Check the menu item role', async t =\u003e {\n    await t.rightClick('.el');\n\n    const menuItem = await getContextMenuItem(['Go To', {label: 'My Function', index: 2}]);\n\n    await t.expect(menuItem.visible).ok();\n});\n```\n\n### getMainMenuItems\n\nGets an array of snapshots of the application's main menu items. If an item has a submenu, it will also be represented as an array of snapshots.\n\n```js\nasync function getMainMenuItems ()\n```\n\nYou can check properties available in snapshots\n[here](https://github.com/electron/electron/blob/master/docs/api/menu-item.md).\n\n**Example**\n\n```js\nimport { getMainMenuItems } from 'testcafe-browser-provider-electron';\n\nfixture `Electron test`\n    .page('./index.html');\n\ntest('Menu should contains the proper list of items', async t =\u003e {\n    const menuItems = (await getMainMenuItems()).map(item =\u003e item.label);\n\n    await t.expect(menuItems).eql(['File', 'Edit', 'Help']);\n});\n```\n\n### getContextMenuItems\n\nGets an array of item snapshots from the **most recently** opened context menu. If an item has a submenu, it will also be represented as an array of snapshots.\n\n```js\nasync function getContextMenuItems ()\n```\n\nYou can check properties available in snapshots\n[here](https://github.com/electron/electron/blob/master/docs/api/menu.md),\n\n**Example**\n\n```js\nimport { getContextMenuItems } from 'testcafe-browser-provider-electron';\n\nfixture `Electron test`\n    .page('./index.html');\n\ntest('Context menu should contains the proper list of items', async t =\u003e {\n    await t.rightClick('.element-with-context-menu');\n\n    const menuItems = (await getContextMenuItems()).map(item =\u003e item.label);\n\n    await t.expect(menuItems).eql(['Cut', 'Copy', 'Properties']);\n});\n```\n\n### clickOnMainMenuItem\n\nPerforms a click on the specified main menu item (`menuItem`).\n\n```js\nasync function clickOnMainMenuItem (menuItem, modifiers)\n```\n\nParameter          | Type   | Description\n------------------ | ------ | -----\n`menuItem` | String \u0026#124; Object | The main menu item to click.\n`modifiers` | Object | Control keys held when clicking the menu item.\n\nIf you specify a string in the `menuItem` parameter, it will be passed to the [getMainMenuItem](#getmainmenuitem) function and the returned value will be used. Alternatively, you can pass a value returned by the [getMainMenuItem](#getmainmenuitem) or [getMainMenuItems](#getmainmenuitems) function.\n\nUse the `modifiers` parameter to specify state of the control keys (`Shift`, `Ctrl`, `Alt`, `Meta`). The default value is\n\n```json\n{\n    \"shift\": false,\n    \"ctrl\":  false,\n    \"alt\":   false,\n    \"meta\":  false\n}\n```\n\n**Examples**\n\n```js\nimport { clickOnMainMenuItem } from 'testcafe-browser-provider-electron';\n\nfixture `Test Electron`\n   .page('./index.html');\n\ntest('Should open search panel', async t =\u003e {\n   await clickOnMainMenuItem(['Main Menu', 'Edit', 'Find...']);\n\n   await searchPanel = Selector('.search-panel');\n\n   await expect(searchPanel.count).eql(1);\n});\n```\n\n```js\nimport { clickOnMainMenuItem, getMainMenuItems } from 'testcafe-browser-provider-electron';\n\nfixture `Test Electron`\n    .page('./index.html');\n\ntest('Should create new file', async t =\u003e {\n    await clickOnMainMenuItem(['File', 'New']);\n    //Or\n    await clickOnMainMenuItem((await getMainMenuItems())[0].submenu[0])\n\n    await newFile = Selector('.file-item').withText('New File');\n\n    await expect(newFile.count).eql(1);\n});\n```\n\n### clickOnContextMenuItem\n\nPerforms a click on the specified menu item (`menuItem`) of the **most recently** opened context menu.\n\n```js\nasync function clickOnContextMenuItem (menuItem, modifiers)\n```\n\nParameter          | Type   | Description\n------------------ | ------ | -----\n`menuItem` | String \u0026#124; Object | The main menu item to click.\n`modifiers` | Object | Control keys held when clicking the menu item.\n\nIf you specify a string in the `menuItem` parameter, it will be passed to the [getContextMenuItem](#getcontextmenuitem) function and the returned value will be used. Alternatively, you can pass a value returned by the [getContextMenuItem](#getcontextmenuitem) or [getContextMenuItems](#getcontextmenuitems) function.\n\nUse the `modifiers` parameter to specify state of the control keys (`Shift`, `Ctrl`, `Alt`, `Meta`). The default value is\n\n```json\n{\n    \"shift\": false,\n    \"ctrl\":  false,\n    \"alt\":   false,\n    \"meta\":  false\n}\n```\n\n**Examples**\n\n```js\nimport { clickOnContextMenuItem } from 'testcafe-browser-provider-electron';\n\nfixture `Test Electron`\n    .page('./index.html');\n\ntest('Should open properties of element', async t =\u003e {\n    await t.rightClick('.el');\n    await clickOnContextMenuItem(['Properties...']);\n\n    await elPropsPanel = Selector('.item-properties-panel');\n\n    await expect(elPropsPanel.count).eql(1);\n});\n```\n\n### setElectronDialogHandler\n\nSets a function that will handle native Electron dialogs.\n\n```js\nasync function setElectronDialogHandler (handler, dependencies) \n```\n\nParameter          | Type   | Description\n------------------ | ------ | -----\n`handler` | Function | A function that will handle Electron dialogs.\n`dependencies` | Object | Variables passed to the `handler` function's scope as global variables.\n\nThe `handler` function has the following signature.\n\n```js\nfunction handler (type, ...args)\n```\n\nThis function must be synchronous. It will be invoked with the dialog type `type`, and the arguments `args`\nfrom the original dialog function.\n\nThe `type` parameter takes one of the following values: \n\n* `open-dialog`,\n* `save-dialog`,\n* `message-box`,\n* `error-box`,\n* `certificate-trust-dialog`.\n\n**Example**\n\n```js\nimport { setElectronDialogHandler } from 'testcafe-browser-provider-electron';\n\nfixture `Electron test`\n    .page('./index.html');\n\ntest('Test project opening', async t =\u003e {\n    await setElectronDialogHandler((type, browserWindow, options) =\u003e {\n        //browserWindow, options are standard arguments of the opening dialog, you can use it for your purposes\n        if(type !== 'open-dialog')\n            return;\n\n        //it returns the file path from the open dialog\n        return ['/home/user/project_name'];\n    });\n\n    await t\n        .click('.open-project')\n        //Here the open directory dialog opens and returns the path '/home/user/project_name'\n        //After this, we check that the project was opened to get its name\n        .expect('.project-name').eql('project_name');\n});\n```\n\n## Author\n\nDeveloper Express Inc. (https://devexpress.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevexpress%2Ftestcafe-browser-provider-electron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevexpress%2Ftestcafe-browser-provider-electron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevexpress%2Ftestcafe-browser-provider-electron/lists"}