@wdio/repl
Advanced tools
+103
-109
@@ -1,114 +0,108 @@ | ||
| /** | ||
| * | ||
| * This command helps you to debug your integration tests. It stops the running browser and gives | ||
| * you time to jump into it and check the state of your application (e.g. using dev tools). | ||
| * Your terminal transforms into a [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) | ||
| * interface that will allow you to try out certain commands, find elements and test actions on | ||
| * them. | ||
| * | ||
| * [](https://webdriver.io/img/repl.gif) | ||
| * | ||
| * If you run the WDIO testrunner make sure you increase the timeout property of the test framework | ||
| * you are using (e.g. Mocha or Jasmine) in order to prevent test termination due to a test timeout. | ||
| * Also avoid executing the command with multiple capabilities running at the same time. | ||
| * | ||
| * <iframe width="560" height="315" src="https://www.youtube.com/embed/xWwP-3B_YyE" frameBorder="0" allowFullScreen></iframe> | ||
| * | ||
| * <example> | ||
| :debug.js | ||
| it('should demonstrate the debug command', () => { | ||
| $('#input').setValue('FOO') | ||
| browser.debug() // jumping into the browser and change value of #input to 'BAR' | ||
| const value = $('#input').getValue() | ||
| console.log(value) // outputs: "BAR" | ||
| }) | ||
| * </example> | ||
| * | ||
| * @alias browser.debug | ||
| * @type utility | ||
| * | ||
| */ | ||
| import vm from 'node:vm'; | ||
| import repl from 'node:repl'; | ||
| import { STATIC_RETURNS, INTRO_MESSAGE, DEFAULT_CONFIG } from './constants.js'; | ||
| export default class WDIORepl { | ||
| static introMessage = INTRO_MESSAGE; | ||
| _config; | ||
| _isCommandRunning = false; | ||
| _replServer; | ||
| constructor(config) { | ||
| this._config = Object.assign(DEFAULT_CONFIG, { eval: this.eval.bind(this) }, config); | ||
| // src/index.ts | ||
| import vm from "node:vm"; | ||
| import repl from "node:repl"; | ||
| // src/constants.ts | ||
| var STATIC_RETURNS = { | ||
| driver: "[WebdriverIO REPL client]", | ||
| browser: "[WebdriverIO REPL client]", | ||
| $: "[Function: findElement]", | ||
| $$: "[Function: findElements]" | ||
| }; | ||
| var INTRO_MESSAGE = ` | ||
| The execution has stopped! | ||
| You can now go into the browser or use the command line as REPL | ||
| (To exit, press ^C again or type .exit) | ||
| `; | ||
| var DEFAULT_CONFIG = { | ||
| commandTimeout: 5e3, | ||
| prompt: "\u203A ", | ||
| useGlobal: true, | ||
| useColor: true | ||
| }; | ||
| // src/index.ts | ||
| var WDIORepl = class { | ||
| static introMessage = INTRO_MESSAGE; | ||
| _config; | ||
| _isCommandRunning = false; | ||
| _replServer; | ||
| constructor(config) { | ||
| this._config = Object.assign( | ||
| DEFAULT_CONFIG, | ||
| { eval: this.eval.bind(this) }, | ||
| config | ||
| ); | ||
| } | ||
| eval(cmd, context, filename, callback) { | ||
| if (this._isCommandRunning) { | ||
| return; | ||
| } | ||
| eval(cmd, context, filename, callback) { | ||
| if (this._isCommandRunning) { | ||
| return; | ||
| } | ||
| if (cmd && STATIC_RETURNS[cmd.trim()]) { | ||
| return callback(null, STATIC_RETURNS[cmd.trim()]); | ||
| } | ||
| vm.createContext(context); | ||
| this._isCommandRunning = true; | ||
| return this._runCmd(cmd, context, callback); | ||
| if (cmd && STATIC_RETURNS[cmd.trim()]) { | ||
| return callback(null, STATIC_RETURNS[cmd.trim()]); | ||
| } | ||
| _runCmd(cmd, context, callback) { | ||
| try { | ||
| const result = vm.runInContext(cmd, context); | ||
| return this._handleResult(result, callback); | ||
| } | ||
| catch (e) { | ||
| this._isCommandRunning = false; | ||
| return callback(e, undefined); | ||
| } | ||
| vm.createContext(context); | ||
| this._isCommandRunning = true; | ||
| return this._runCmd(cmd, context, callback); | ||
| } | ||
| _runCmd(cmd, context, callback) { | ||
| try { | ||
| const result = vm.runInContext(cmd, context); | ||
| return this._handleResult(result, callback); | ||
| } catch (e) { | ||
| this._isCommandRunning = false; | ||
| return callback(e, void 0); | ||
| } | ||
| _handleResult(result, callback) { | ||
| if (!result || typeof result.then !== 'function') { | ||
| this._isCommandRunning = false; | ||
| return callback(null, result); | ||
| } | ||
| let timeoutCalled = false; | ||
| const timeout = setTimeout(() => { | ||
| callback(new Error('Command execution timed out'), undefined); | ||
| this._isCommandRunning = false; | ||
| timeoutCalled = true; | ||
| }, this._config.commandTimeout); | ||
| result.then((res) => { | ||
| /** | ||
| * don't do anything if timeout was called | ||
| */ | ||
| if (timeoutCalled) { | ||
| return; | ||
| } | ||
| this._isCommandRunning = false; | ||
| clearTimeout(timeout); | ||
| return callback(null, res); | ||
| }, (e) => { | ||
| /** | ||
| * don't do anything if timeout was called | ||
| */ | ||
| if (timeoutCalled) { | ||
| return; | ||
| } | ||
| this._isCommandRunning = false; | ||
| clearTimeout(timeout); | ||
| const errorMessage = e ? e.message : 'Command execution timed out'; | ||
| const commandError = new Error(errorMessage); | ||
| delete commandError.stack; | ||
| return callback(commandError, undefined); | ||
| }); | ||
| } | ||
| _handleResult(result, callback) { | ||
| if (!result || typeof result.then !== "function") { | ||
| this._isCommandRunning = false; | ||
| return callback(null, result); | ||
| } | ||
| start(context) { | ||
| if (this._replServer) { | ||
| throw new Error('a repl was already initialized'); | ||
| } | ||
| if (context) { | ||
| const evalFn = this._config.eval; | ||
| this._config.eval = function (cmd, _, filename, callback) { | ||
| return evalFn.call(this, cmd, context, filename, callback); | ||
| }; | ||
| } | ||
| this._replServer = repl.start(this._config); | ||
| return new Promise((resolve) => { | ||
| return this._replServer.on('exit', resolve); | ||
| }); | ||
| let timeoutCalled = false; | ||
| const timeout = setTimeout( | ||
| () => { | ||
| callback(new Error("Command execution timed out"), void 0); | ||
| this._isCommandRunning = false; | ||
| timeoutCalled = true; | ||
| }, | ||
| this._config.commandTimeout | ||
| ); | ||
| result.then((res) => { | ||
| if (timeoutCalled) { | ||
| return; | ||
| } | ||
| this._isCommandRunning = false; | ||
| clearTimeout(timeout); | ||
| return callback(null, res); | ||
| }, (e) => { | ||
| if (timeoutCalled) { | ||
| return; | ||
| } | ||
| this._isCommandRunning = false; | ||
| clearTimeout(timeout); | ||
| const errorMessage = e ? e.message : "Command execution timed out"; | ||
| const commandError = new Error(errorMessage); | ||
| delete commandError.stack; | ||
| return callback(commandError, void 0); | ||
| }); | ||
| } | ||
| start(context) { | ||
| if (this._replServer) { | ||
| throw new Error("a repl was already initialized"); | ||
| } | ||
| } | ||
| if (context) { | ||
| const evalFn = this._config.eval; | ||
| this._config.eval = function(cmd, _, filename, callback) { | ||
| return evalFn.call(this, cmd, context, filename, callback); | ||
| }; | ||
| } | ||
| this._replServer = repl.start(this._config); | ||
| return new Promise((resolve) => { | ||
| return this._replServer.on("exit", resolve); | ||
| }); | ||
| } | ||
| }; | ||
| export { | ||
| WDIORepl as default | ||
| }; |
+6
-4
| { | ||
| "name": "@wdio/repl", | ||
| "version": "9.0.0-alpha.426+d760644c4", | ||
| "version": "9.0.0", | ||
| "description": "A WDIO helper utility to provide a repl interface for WebdriverIO", | ||
@@ -28,4 +28,6 @@ "author": "Christian Bromann <mail@bromann.dev>", | ||
| "exports": { | ||
| ".": "./build/index.js", | ||
| "./package.json": "./package.json" | ||
| ".": { | ||
| "import": "./build/index.js", | ||
| "types": "./build/index.d.ts" | ||
| } | ||
| }, | ||
@@ -39,3 +41,3 @@ "typeScriptVersion": "3.8.3", | ||
| }, | ||
| "gitHead": "d760644c4c6e1ef910c0bee120cb422e25dbbe06" | ||
| "gitHead": "957693463371a4cb329395dcdbce8fb0c930ab93" | ||
| } |
| export const STATIC_RETURNS = { | ||
| driver: '[WebdriverIO REPL client]', | ||
| browser: '[WebdriverIO REPL client]', | ||
| $: '[Function: findElement]', | ||
| $$: '[Function: findElements]' | ||
| }; | ||
| export const INTRO_MESSAGE = ` | ||
| The execution has stopped! | ||
| You can now go into the browser or use the command line as REPL | ||
| (To exit, press ^C again or type .exit) | ||
| `; | ||
| export const DEFAULT_CONFIG = { | ||
| commandTimeout: 5000, | ||
| prompt: '\u203A ', | ||
| useGlobal: true, | ||
| useColor: true | ||
| }; |
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
0
-100%2
-33.33%8505
-17.61%8
-11.11%167
-13.02%