Giter Club home page Giter Club logo

wdio-electron-service's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wdio-electron-service's Issues

wdio-electron-service does not work when contextIsolation is false

which, most likely, it is still true when rephrased like ' wdio-electron-service cannot be used for most of the existing (big) projects' or
'wdio-electron-service can be used only on new electron projects'

If I try to use wdio-electron-service with contextIsolation: false, I get an error like 'contextBridge needs contextIsolation to be true' and nothing works.

This is happening because the below code uses contextBridge

https://github.com/webdriverio-community/wdio-electron-service/blob/main/src/preload.ts

But if I put contextIsolation: true for getting wdio-electron-service to work I get another error like 'require function not defined' and nothing works. This is happening because I have an existing project where the require function is needed and this project cannot be easily updated as per the latest Electron security best practices (this will be done but it will take a longer period of time to migrate all the existing code).

I understand that the newer versions of Electron, for security reasons, strongly recommends having contextIsolation:true and this is good for new projects but for older and bigger projects it takes more effort to update all the existing code which means that many times people will use contextIsolation:false for such projects.

I believe that wdio-electron-service should work no matter if contextIsolation:true or contextIsolation:false since your library should enable people to use webdriver.io in electron no matter if contextIsolation:true or contextIsolation:false (people will use this flag not because they want to but because for existing projects, they have no other choice).

Support multiple custom APIs

We should support the user supplying an array of mappings for browser extensions to access custom API functions on the main process. Unless a clever solution can be found, they will need to use the same contextBridge channel.

Improve mocking behavior

Currently you can mock specific ElectronJS apis via, e.g.:

await browser.electron.mock('dialog', 'showOpenDialog', 'dialog opened!');

This approach has several limitations:

  • it doesn't allow to validate whether this method was actually called in the Electron process
  • it doesn't allow to execute alternative code

I suggest to align the mocking interface to what we strive for in WebdriverIO as well. The following primitives should be not to difficult to implement in the serviceL

  1. an execute command that allows to run arbitrary code in the main process
const res = await browser.electron.execute((electron) => {
  electron.dialog.showOpenDialog('foobar')
  return 123
})
// console.log(res) // outputs 123
  1. extending the mock command to return a mock object we can use in the mock matchers
const dialog = await browser.electron.mock('dialog', 'showOpenDialog')
expect(dialog).toBeCalledTimes(2)
expect(dialog).toBeCalledWith('Hello World!')

Use native WDIO Chromedriver download mechanism

With the recent release of WebdriverIO that includes new features around browser driver management it seems to have broken this service capabilities to do that for the user. I propose to have it set hostname and port capabilities so that WebdriverIO recognises to not have to setup the browser and driver itself.

Maybe this service can leverage these features and remove some code that prior downloaded Chromedriver.

webdriverio v > 8.13 breaks wdio-electron-service

I can run with webdriverio v8.13, but in later versions the chrome driver isn't resolved correctly.

I noticed that as of 8.14 wdio-chromdriver-service is deprecated and no longer maintained. There's also a blog post about how 8.14 handles chrome driver resolution for you.

Passing an electronVersion is ignored as is passing a chromedriverCustomPath. The runner located the electron executable and refuses to run because the driver it has selected (for the installed chrome) isn't a match.

I can run with 8.13, but after, including 8.15 seems DOA due to upstream changes.

Need help in the plugin configuration!

Hello,

I've started to test an application with Electron 22.0.0. We asked for the dialog support for electron what is come true, but now I ran into some configuration errors. Somebody can help me out what did I missed? (application build on windows 'release' dir. Angular 15 app.

when i run test i got:

 Cannot read properties of undefined (reading 'electron')
[electron 22.0.0 win32 #0-0] TypeError: Cannot read properties of undefined (reading 'electron')  
[electron 22.0.0 win32 #0-0]     at LicenseSelector.<anonymous> (C:\Users\user\IdeaProjects\electronapp\test\pageobjects\page.ts:64:19)

main.ts

import('wdio-electron-service/dist/main')

const VISIBLE_SIDEBAR_MIN_WINDOWS_WIDTH = 1050
const VISIBLE_SIDEBAR_MIN_WINDOWS_HEIGHT = 750

 win = new BrowserWindow({
    width: initialWindowWidth,
    height: initialWindowHeight,
    minWidth: 800,
    minHeight: 600,
    title: CommonConstants.APP_TITLE,
    icon: path.join(assetsDir, 'icon.icns'),
    center: true,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
      preload: path.join(__dirname, 'preload.js'),
      sandbox: false,
    },
  })

preload.js

// build in support
require('wdio-electron-service/dist/preload')

wdio.conf.ts

import * as Path from 'path'

// More info on
// https://webdriver.io/docs/configurationfile/
export const config = {
  runner: 'local',
  specs: [Path.join(__dirname, 'test', 'specs', '*.ts')],
  maxInstances: 1,
  capabilities: [
    {
      maxInstances: 1,
      browserName: 'electron',
    },
  ],
  autoCompileOpts: {
    autoCompile: true,
    tsNodeOpts: {
      project: './test/tsconfig.json',
      transpileOnly: true,
    },
  },
  logLevel: 'info',
  bail: 1,
  baseUrl: 'http://127.0.0.1',
  waitforTimeout: 10000,
  connectionRetryTimeout: 120000,
  connectionRetryCount: 3,
  services: [
    [
      'electron',
      {
        appPath: Path.join(__dirname, 'release'),
        appName: 'Application',
        electronVersion: '22.0.0',
      },
    ],
  ],
  framework: 'mocha',
  reporters: ['spec'],
  mochaOpts: {
    ui: 'bdd',
    retries: 0,
    timeout: 30 * 1000, // 30 sec
  },
}

page.ts

import { browser } from 'wdio-electron-service'

/**
 * Main page object containing all methods, selectors and functionality
 * that is shared across all page objects
 */
export default class Page {
  /**
   * Get title from electron window
   */
  async title(): Promise<string> {
    return (await browser.electron.app('getName')) as Promise<string> // this line cause the error
  }

   /**
   * Wait for upload filepath via browser windows
   * @param selector element id for open the browser
   * @param path path to file
   */
  async waitForFileUpload(selector: string, path: string) {
    await browser.electron.mock('dialog', 'showOpenDialog', 'path/to/file') // this line cause the error
    const result = await browser.electron.dialog('showOpenDialog')  // this line cause the error
    console.log('result:' + result)
  }
}

package.json

{
  "main": "main.js",
  "scripts": {
    "wdio": "pnpm exec wdio run ./wdio.conf.ts"
  },
  "dependencies": {
    "@electron/remote": "2.0.9",
...
    "electron-updater": "5.3.0",
...
    "wdio-electron-service": "4.1.0",
    "webdriverio": "8.11.2"
  },
  "devDependencies": {
...
    "@wdio/cli": "8.6.9",
    "@wdio/devtools-service": "8.6.9",
    "@wdio/junit-reporter": "8.6.8",
    "@wdio/spec-reporter": "8.6.8",
    "@wdio/local-runner": "8.6.9",
    "@wdio/mocha-framework": "8.6.8",
...
    "electron": "22.0.0",
    "electron-builder": "23.6.0",
    "electron-reload": "2.0.0-alpha.1",
...
    "wait-on": "7.0.1",
    "wdio-chromedriver-service": "8.1.1",
    "wdio-cucumberjs-json-reporter": "4.4.3",
    "wdio-eslinter-service": "0.0.4",
    "wdio-json-reporter": "3.0.0",
    "wdio-wait-for": "3.0.2",
    "webdriver-manager": "12.1.8",
...
}

Chromedriver version mismatch issues

We currently use electron-chromedriver to download the version of chromedriver which works with the latest version of electron, but if you are testing an app which is built with a different electron version then you will get version mismatch errors.

The following workaround needs to be properly documented and also to work with windows:

npm i --save chromedriver@94
        chromedriver: {
          port: 9519,
          logFileName: 'wdio-chromedriver.log',
          chromedriverCustomPath: 'node_modules/chromedriver/bin/chromedriver'
        }
npm i --save electron-chromedriver@16
        chromedriver: {
          port: 9519,
          logFileName: 'wdio-chromedriver.log',
          chromedriverCustomPath: require.resolve('electron-chromedriver')
        }

E2E / integration tests

Would be nice to have some automated tests for this verifying the integration with WDIO. The wdio-geckodriver-service has a nice solution in this area but relies on Firefox being available on the GH action runner. For Electron it would be more complicated, requiring a sample app to be built. Could pull down wdio-electron-service-example and run those E2Es, or find some way to integrate that repo with this one.

https://github.com/webdriverio-community/wdio-geckodriver-service/blob/main/test/wdio.conf.js

Fix TS typing of Electron APIs

If you want to use the Electron APIs the browser commands are not correctly typed. This is made more complicated by customisable APIs, in this case I think we should just let the user provide typings for the custom commands and we will make types available for the commands provided by wdio-electron-service.

wdio-electron-service-example should be switched to TS as part of fixing this.

Support Electron Builder JSON config

The electron-builder config is currently assumed to be in package.json, it can also be in electron-builder.json. EB supports YML/TOML flavours of this file too but I suspect usage of those is minimal so we should just support the JSON variant for now.

Improve CLI integration

Ideally the WDIO CLI should auto-detect configuration in as many cases as possible when using electron-builder or Electron Forge. Most users should not have to find the path to their app binary themselves.

  • Use pkg-up to find the nearest package.json
  • Analyse the file to determine whether electron-builder or @electron-forge/cli is being used
    • If no build tool found, ask the user if their Electron app is located in a different repo
      • If YES, ask for the path to that repo
        • Analyse the repo's package.json to determine whether electron-builder or @electron-forge/cli is being used
          • If no build tool found, ask the user for the path to the binary of their app and set appBinaryPath
          • If a build tool is found, analyse build tool config
      • if NO, ask the user for the path to the binary of their app and set appBinaryPath
    • If a build tool is found, analyse build tool config

Build Tool Config Analysis

https://www.electron.build/configuration/configuration
https://www.electronforge.io/config/configuration

  • If electron-builder is found, try to read config from the following in order:
    • package.json
    • electron-builder.json (if parse fail - try parsing as JSON5)
    • electron-builder.json5
    • electron-builder.yml
    • electron-builder.toml
  • If @electron-forge/cli is found, try to read config from the following in order:
    • package.json
    • JS file specified by config.forge key in package.json
    • forge.config.js
  • Use values read from config (app name, output directory) and getBinaryPath to set the appBinaryPath
  • If configuration for either tool is not found, notify the user, ask the user for the path to the binary of their app and set appBinaryPath

Chromedriver process on Windows not cleaned up after specs complete

Overview

While testing out the wdio-electron-service-example project on a Windows machine I noticed that the chromedriver process was not being cleaned up after running the test suite (with npx wdio).

Details

I believe this line in the launcher is the start of the issue (snippet copied below).

if (isWin) {
  process.env.WDIO_ELECTRON_NODE_PATH = process.execPath;
  process.env.WDIO_ELECTRON_CHROMEDRIVER_PATH = chromedriverServiceOptions.chromedriverCustomPath;
  chromedriverServiceOptions.chromedriverCustomPath = join(__dirname, '..', 'bin', 'chrome-driver.bat');
}

This is overriding any path to chromedriver (whether custom or default) to instead use this .bat file.

@echo off
"%WDIO_ELECTRON_NODE_PATH%" "%WDIO_ELECTRON_CHROMEDRIVER_PATH%" %*
if ERRORLEVEL 1 exit /b 1
exit /b 0

Now, this does make sense since the default chromedriverCustomPath points to node_modules\electron-chromedriver\chromedriver.js. However, the .bat file does not wait for node to exit before the terminal running the .bat file is allowed to exit. Node is allowed to keep running while its original parent terminal process has died, which causes problems in the wdio-chromedriver-service.

At this line of the wdio-chromedriver-service the child process for chromedriver is spawned and a reference kept, although because of the .bat file override earlier, this.process refers to the terminal process that will soon start Node.

By the time we hit the this.process.kill() command in the onComplete service handler, this.process has already long since died and the Node/chromedriver processes are running as their own process tree, disconnected from this.process.

An example process tree might look like this (pids taken from my last run):

cmd.exe (28956) [this.process] <-- dies immediately after node.exe is started
|____ node.exe (22832)
      |____ chromedriver.exe (24100)

Solution

A real solution to this issue will likely involve tracking the child node process or communicating with it to collaboratively shutdown. Unfortunately I don't have anything like that to offer right now, though I do have a relatively small workaround fix that would at least mitigate the problem.

The use of the .bat file launcher seems to only make sense if a chromedriver file is provided that needs to run within node (js file). If a user provides a path to chromedriver.exe in chromedriverCustomPath, it is currently still passed through to the .bat file to be run in Node. I propose that we only use the .bat file for .js files and allow any other extension to be run directly via child_process.spawn().

Something like (in launcher.ts):

import { join, extname } from 'path';
// snip...

if (isWin) {
  process.env.WDIO_ELECTRON_NODE_PATH = process.execPath;
  process.env.WDIO_ELECTRON_CHROMEDRIVER_PATH = chromedriverServiceOptions.chromedriverCustomPath;
  const shouldRunInNode = extname(chromedriverServiceOptions.chromedriverCustomPath) === '.js';
  if (shouldRunInNode) {
    chromedriverServiceOptions.chromedriverCustomPath = join(__dirname, '..', 'bin', 'chrome-driver.bat');
  }
}

This would allow anyone encountering this issue to specify the chromedriver.exe path themselves and bypass the extra .bat file redirection (from wdio.conf.js):

const config = [
services: [
    [
      'electron',
      {
        appPath: join(__dirname, 'dist'),
        appName: productName,
        appArgs: ['foo', 'bar=baz'],
        chromedriver: {
          port: 9519,
          logFileName: 'wdio-chromedriver.log',
          // provide custom path to .exe to bypass use of .bat file
          chromedriverCustomPath: require.resolve('electron-chromedriver/bin/chromedriver.exe'),
        },
      },
    ],
  ],
  // snip...
]

This work around solves the problem in my case. Specs in the example project complete successfully and the chromedriver process dies at the end. If the work around is acceptable, I would be happy to submit a PR.

SyntaxError: Unexpected token 'export' wdio-electron-service/dist/cjs/index.js:35

Hello,
after initiating a new project using `npm init wdio .', and configuring the electron service as described here, I'm getting the following error message:

@wdio/runner: wdio8-test/node_modules/wdio-electron-service/dist/cjs/index.js:35
export {};
^^^^^^

SyntaxError: Unexpected token 'export'
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1176:20)
    at Module._compile (node:internal/modules/cjs/loader:1218:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
    at Object.require.extensions.<computed> [as .js] (wdio8-test/node_modules/ts-node/src/index.ts:1608:43)
    at Module.load (node:internal/modules/cjs/loader:1117:32)
    at Module._load (node:internal/modules/cjs/loader:958:12)
    at Function.hookedLoader [as _load] (wdio8-test/node_modules/mockery/mockery.js:111:12)
    at Module.require (node:internal/modules/cjs/loader:1141:19)
    at require (node:internal/modules/cjs/helpers:110:18)

The wdio.conf.ts is this:

import type { Options } from "@wdio/types";
import * as path from "path";

export const config: Options.Testrunner = {
  runner: "local",
  outputDir: "all-logs",
  autoCompileOpts: {
    autoCompile: true,
    tsNodeOpts: {
      files: true,
      project: "./tsconfig.json",
      transpileOnly: true,
    },
  },
  specs: ["./features/**/*.feature"],
  exclude: [],
  maxInstances: 10,
  capabilities: [
    {
      maxInstances: 5,
      browserName: "chrome",
      acceptInsecureCerts: true,
    },
  ],
  logLevel: "trace",
  bail: 0,
  baseUrl: "http://localhost",
  waitforTimeout: 10000,
  connectionRetryTimeout: 120000,
  connectionRetryCount: 3,
  services: [
    [
      "electron",
      {
        appPath: path.join(__dirname, "binaries"),
        appName: "App Name",
        electronVersion: "22.0.0",
      },
    ],
  ],
  framework: "cucumber",
  reporters: ["spec"],
  cucumberOpts: {
    require: ["./features/step-definitions/steps.ts"],
    backtrace: true,
    requireModule: [],
    dryRun: false,
    failFast: false,
    snippets: true,
    source: true,
    strict: false,
    tagExpression: "",
    timeout: 60000,
    ignoreUndefinedDefinitions: false,
  },
};

and the package.json like this:

{
  "name": "wdio8-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "wdio": "wdio run ./wdio.conf.ts"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@wdio/cli": "^8.6.7",
    "@wdio/cucumber-framework": "^8.6.6",
    "@wdio/local-runner": "^8.6.7",
    "@wdio/spec-reporter": "^8.6.6",
    "chromedriver": "^111.0.0",
    "prettier": "^2.8.6",
    "ts-node": "^10.9.1",
    "typescript": "^5.0.2",
    "wdio-chromedriver-service": "^8.1.1",
    "wdio-electron-service": "^4.0.0"
  }
}

node version is 18.15.0, tried it also with node 16.14.0.
For me, it looks like it tries to use the CommonJS version of wdio-electron-service, but everything else uses esm already.

Might this be a problem?

Setting "type": "module" in package.json leads to this error instead:

wdio run ./wdio.conf.ts

2023-03-22T09:14:30.671Z ERROR @wdio/config:ConfigParser: Failed loading configuration file: file:///wdio8-test/wdio.conf.ts: exports is not defined in ES module scope
ReferenceError: exports is not defined in ES module scope
at file:///wdio8-test/wdio.conf.ts:2:23
at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

Process finished with exit code 1

wdio-electron-service & docker: DevToolsActivePort file doesn't exist

Hey, trying to run cucumber tests against electron inside docker in Jenkins and we're seeing this kinda error:

Request failed with status 500 due to unknown error: Chrome failed to start: exited abnormally.
(DevToolsActivePort file doesn't exist)
(The process started from chrome location ... is no longer running, so ChromeDriver is assuming that Chrome has crashed.)

Internet suggests that I should be passing --disable-dev-shm-usage flag for the chromium, but haven't been able to do that.
Any helpers or advice that I might have overlooked?

I'm doing a migration from spectron to wdio at the moment.
The docker entrypoint making use of xvfb was configured already for spectron and I guess it should work similarly for the wdio also?

wdio.conf.ts

  services: [
    [
      'electron',
      {
        appPath: join(__dirname, '../../../package'),
        appName: productName,
        appArgs: [
          "--disable-infobars", // not sure if this is needed
          "--disable-dev-shm-usage",
          "--no-sandbox", // not sure if this is needed
          "--headless",  // not sure if this is needed
        ],
        chromedriver: {
          port: 9519,
          logFileName: 'wdio-chromedriver.log',
        },
      },
    ],
  ],

Grateful for any tips :)

Electron API support

The Spectron fork from which this service was derived supported a number of Electron APIs, we should recreate this but with a different approach.

Despite the size and scope of the APIs provided by Electron, the number of functions which may be useful for testers is actually pretty small, so the greedy property looping and filtering of the Spectron fork can be ditched in favour of a whitelist. This has the benefit of avoiding the problem experienced by the Enzyme React testing library in which users would rely on directly manipulating component state, props, context in their suites, which results in immensely brittle tests; we only really want to be exposing Electron APIs which provide a way of testing values which are difficult or impossible to get hold of through WebdriverIO Testing Library or the browser object.

Other constraints on what we allow access to (and how) will be:

  • the desire to avoid duplication of WDIO/Webdriver functionality
  • the desire to avoid encouraging poor testing practices (c.f. Enzyme) through
    • testing of Electron APIs themselves
    • testing of OS functionality
    • manipulating Electron internals in a way that a user would not have access to via the app
  • the IPC security model; we can't pass complex objects between main and renderer processes.

API functions can be made available on the browser object, namespaced under electron. A minimal set of functionality will be exposed to begin with, users can raise issues / submit PRs to expose more Electron functionality if they want and documentation should be updated to encourage this.

This issue will be closed once the initial basic level of API support has been enabled.

Docs Update

The documentation for the service would benefit from being split into separate files with the main README dedicated to an overview of the service, "quick setup" section and links. We could also leverage the Github Wiki.

Make session reload configurable

Currently we reload the session between tests to prevent state bleed, this should be configurable so that users can manage their own test state if they wish.

PNMP for install

When running:

npm i -D wdio-electron-service

I am getting:
'''
npx only-allow pnpm

npx: installed 20 in 3.69s
╔═════════════════════════════════════════════════════════════╗
║ ║
║ Use "pnpm install" for installation in this project. ║
║ ║
║ If you don't have pnpm, install it via "npm i -g pnpm". ║
║ For more details, go to https://pnpm.js.org/


I am using:
npm: '8.5.2',
  node: '14.18.1'
  
 Is pnmp required to use the service?

Electron Dialog Support?

Hi!

I really like your work! Now I've just ran into a problem, there is a button with no inputto file upload in a project. I need to handle the electron dialog with sendkeys or just retrun some value as close event. Is there any solution for that?

Thanks and again great work!

Multi remote for electron apps

Could we consider extending multi-remote capabilities to this service?

Use cases are to drive more than one app in parallel as well as a browser, etc.

Review Chromedriver dependency

We are currently requiring chromedriver as a peerdep and initial testing suggests it is required - it seems the use of electron-chromedriver does not fulfil this.

Possible options available:

  • switch electron-chromedriver for chromedriver and change docs to reflect that chromedriver is a required peerdep
  • update wdio-chromedriver-service to make chromedriver an optional peerdep
  • something else?

Sending messages through ipcMain?

Hi,

we have an Electron app that is mostly tested through wdio but some tests did rely on Spectron. I was thinking of just writing ipcMain listeners in the test bundle of our app whenever the test suite needs to do some electron-main specific functionality. Does this service provide a way to send a message to ipcMain of the app from our test suite? Or, is there a way to do that even without using this service?

Thanks

Compilation Errors after upgrading TS to 5.1.x

Upgrading TS to 5.1.x results in the following compilation errors:

error TS2688: Cannot find type definition file for '@wdio/globals/types'.
  The file is in the program because:
    Entry point of type library '@wdio/globals/types' specified in compilerOptions

  tsconfig.json:8:23
    8     "types": ["node", "@wdio/globals/types"]
                            ~~~~~~~~~~~~~~~~~~~~~
    File is entry point of type library specified here.

src/service.ts:179:27 - error TS2684: The 'this' context of type 'WebdriverIO.Browser' is not assignable to method's 'this' of type 'import("<snip />/wdio-electron-service/node_modules/.pnpm/[email protected][email protected]/node_modules/webdriverio/build/types").Browser'.
  Type 'Browser' is missing the following properties from type 'Browser': sessionStatus, sessionNew, sessionEnd, sessionSubscribe, and 25 more.

179             return await (browser.executeAsync as WebdriverClientFunc)(callApi, bridgeProp, args);
                              ~~~~~~~

src/service.ts:179:27 - error TS2352: Conversion of type '<ReturnValue, InnerArguments extends any[]>(this: Browser | Element, script: string | ((...args: [...innerArgs: InnerArguments, callback: (result?: ReturnValue | undefined) => void]) => void), ...args: InnerArguments) => Promise<...>' to type 'WebdriverClientFunc' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  The 'this' types of each signature are incompatible.
    Type 'Browser' is not comparable to type 'Browser | Element'.
      Type 'Browser' is missing the following properties from type 'Element': elementId, ELEMENT, selector, parent, and 38 more.

179             return await (browser.executeAsync as WebdriverClientFunc)(callApi, bridgeProp, args);
                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Replace custom API with direct access to main process via callback

The custom API is somewhat clunky to use, we might improve this by using a pattern borrowed from Playwright, which evaluates a function in the electron context, passing Electron main process APIs directly into the function. Some investigation is required to ascertain how the following works in Playwright:

  // Launch Electron app.
  const electronApp = await electron.launch({ args: ['main.js'] });

  // Evaluation expression in the Electron context.
  const appPath = await electronApp.evaluate(async ({ app }) => {
    // This runs in the main Electron process, parameter here is always
    // the result of the require('electron') in the main app script.
    return app.getAppPath();
  });

One possibility for this could be the WebContents executeJavaScriptInIsolatedWorld method.

Question: Using electron service with WDIO in a script

Hello! I'm having an issue with trying to get the service up and running when using WDIO in a script running Jest. I've tried a couple of things, and the closest I got was doing the following:

Before test, start chromedriver:
const args = [ chromedriverPath, '--remote-debugging-port=9515', '--url-base=/', '--verbose', ]; const cdProcess = child_process.spawn(process.execPath, args);

Then create my remote:
const app = await remote({ logLevel: 'trace', services: [ [ 'electron', { appPath: appPath, appName: appName, chromedriver: { port: 9515, chromedriverCustomPath: chromedriverPath, logFileName: 'wdio-chromedriver.log', }, }, ], ], capabilities: { browserName: 'chrome', 'goog:chromeOptions': { binary: appExecutable, }, }, port: 9515, });

This will successfully start my electron application and let me do native WDIO things (app.saveScreenshot() works as expected), however I get the following error when trying to use electronApp:

TypeError: app.electronApp is not a function > 90 | const appName = await app.electronApp('getName'); | ^ 91 | console.log(appName);

I'm admittedly VERY new to WDIO so I'm fully aware that I may be missing something silly, but any advice I could get would be very much appreciated.

Thanks!

Download and use the appropriate version of Chromedriver

Initial discussion here.

The user should be able to specify an electron version for which the service will download and use the appropriate version of Chromedriver. Existing customPath prop should still work in case the user wants to roll their own.

Can use https://github.com/electron/get in a similar way to electron-chromedriver, alternatively there is also electron-to-chromium.

Prior art:
https://github.com/webdriverio-community/wdio-vscode-service
https://github.com/electron/chromedriver

Enable customisation of chromeArgs

We should allow customisation of the chromeArgs settings.

The chromeArgs defaults currently used by the service were defined when looking to fix the DevToolsActivePort file doesn't exist error on CI, so in the first instance we should define which defaults are actually required and for what reasons.

Required args should still be applied by the service but with the option for users to override them if they wish. There is some logic around which args are applied (CI / non-Windows platforms); the service should use the default for each required arg only when the user has not specified that particular arg.

Additionally, #47 could be a part of this work.

Conditionally control exposing wdio-electron context bridge items outside test environment

I'm shopping for a Spectron replacement and since I'm looking under the hood...

Spectron exposed electron app innards by being constructed in the test runner and either your app has node integration enabled or it conditionally provided a require function for Spectron to use to gain access. So outside of the testing it had no effect (unless the environment var for testing is set during the pre-load).

The recommended way of getting at the innards with wdio-electron-service it so modify the preload and the content scripts to import scripts that patch the app to expose the innards over the context bridge. This has a lasting effect outside of the testing environment.

Since we use webpack, conditionally including the scripts doesn't work (we're not setup for dynamic imports yet)... but wrapping the included scripts internally with an if might be a way to accomplish this. Though I might just be missing something!

Can you provide a boilerplate for using Electron in Quasar Framework?

You installed the necessary packages with the following command:

npm i -D wdio-electron-service

And you also installed Electron in the Quasar Framework using the following commands:


npm init quasar
...
npx quasar dev -m electron

However, you encountered a problem during the installation process with the following error message:

**npx run ./wdio.conf.js**
? A project named "quasar-project" was detected at "C:\Users\shine\OneDrive\문서\workspace\node\mocha\quasar-project", correct? Yes
? What type of testing would you like to do? Desktop Testing - of Electron Applications
    > https://webdriver.io/docs/desktop-testing/electron
? What is the path to your compiled Electron app? .quasar
? Which framework do you want to use? Mocha (https://mochajs.org/)
? Do you want to use a compiler? TypeScript (https://www.typescriptlang.org/)
? Do you want WebdriverIO to autogenerate some test files? Yes
? Where should these files be located? C:\Users\shine\OneDrive\문서\workspace\node\mocha\quasar-project\test\specs\**\*.ts
? Which reporter do you want to use? spec
? Do you want to add a plugin to your test setup? wait-for
? Do you want to add a service to your test setup? electron
? Do you want me to run `npm install` Yes

Setting up TypeScript...
✔ Success!

Installing wdio packages:
- @wdio/local-runner@latest
- @wdio/mocha-framework@latest
- @wdio/spec-reporter@latest
- wdio-wait-for
- wdio-electron-service
- ts-node
- typescript

added 58 packages, and audited 774 packages in 8s

154 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
✔ Success!

Creating a WebdriverIO config file...
✔ Success!

Autogenerating test files...
✔ Success!

Adding "wdio" script to package.json.
✔ Success!


To run your tests, execute:
$ cd C:\Users\shine\OneDrive\문서\workspace\node\mocha\quasar-project
$ npm run wdio

Adding scripts to package.json
node:internal/modules/cjs/loader:985
  const err = new Error(message);
              ^

Error: Cannot find module 'C:\Users\shine\OneDrive\문서\workspace\node\mocha\quasar-project\run\package.json'
Require stack:
- C:\Users\shine\AppData\Local\npm-cache\_npx\471611576716610c\node_modules\wdio\build\index.js
- C:\Users\shine\AppData\Local\npm-cache\_npx\471611576716610c\node_modules\wdio\bin\wdio.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:985:15)
    at Function.Module._load (node:internal/modules/cjs/loader:833:27)
    at Module.require (node:internal/modules/cjs/loader:1057:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at createWebdriverIO (C:\Users\shine\AppData\Local\npm-cache\_npx\471611576716610c\node_modules\wdio\build\index.js:81:21) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'C:\\Users\\shine\\AppData\\Local\\npm-cache\\_npx\\471611576716610c\\node_modules\\wdio\\build\\index.js',
    'C:\\Users\\shine\\AppData\\Local\\npm-cache\\_npx\\471611576716610c\\node_modules\\wdio\\bin\\wdio.js'
  ]
}

Document Testing Electron Applications in the main docs

We should add a section to the main documentation "Electron Testing" with some documentation how to get started with this service and what a user needs to do to test an Electron application. It would be also nice if we could maybe integrate this into the WDIO configuration wizard.

Use Node testrunner for unit tests

We may be able to remove some dependencies by using the native Node testrunner for unit tests instead of Vitest. Requires investigation once the service has been updated from Node 16 to Node 20, where the Test API is stable.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.