diff --git a/lib/commands/execute.js b/lib/commands/execute.js index 98ceb3d68..d2f7079dd 100644 --- a/lib/commands/execute.js +++ b/lib/commands/execute.js @@ -32,7 +32,8 @@ extensions.execute = async function execute (script, args) { return await this.executeMobile(script, _.isArray(args) ? args[0] : args); } else if (this.isWebContext()) { args = this.convertElementsForAtoms(args); - return await this.executeAtom('execute_script', [script, args]); + const result = await this.executeAtom('execute_script', [script, args]); + return this.cacheWebElements(result); } else { throw new errors.NotImplementedError(); } diff --git a/lib/commands/web.js b/lib/commands/web.js index 1e34b62c9..c45d8dcaf 100644 --- a/lib/commands/web.js +++ b/lib/commands/web.js @@ -203,25 +203,38 @@ helpers._deleteCookie = async function _deleteCookie (cookieName) { await this.executeAtom('execute_script', [script, []]); }; -helpers.cacheWebElements = function cacheWebElements (rawElements) { - if (!(_.isArray(rawElements) || _.isPlainObject(rawElements))) { - throw new errors.UnknownError(`Web element identifiers cannot be parsed from ` + - JSON.stringify(rawElements)); - } - - const cacheElement = (el) => { - const elId = util.unwrapElement(el); - if (!isValidElementIdentifier(elId)) { - throw new errors.UnknownError(`The web element identifier ${JSON.stringify(elId)} cannot be parsed`); - } - // In newer debugger releases element identifiers look like `:wdc:1628151649325` - // We assume it is safe to use these to identify cached elements - const cacheId = _.includes(elId, ':') ? elId : util.uuidV4(); - this.webElementsCache.set(cacheId, elId); - return util.wrapElement(cacheId); - }; +helpers.cacheWebElement = function cacheWebElement (el) { + if (!_.isPlainObject(el)) { + return el; + } + const elId = util.unwrapElement(el); + if (!isValidElementIdentifier(elId)) { + return el; + } + // In newer debugger releases element identifiers look like `:wdc:1628151649325` + // We assume it is safe to use these to identify cached elements + const cacheId = _.includes(elId, ':') ? elId : util.uuidV4(); + this.webElementsCache.set(cacheId, elId); + return util.wrapElement(cacheId); +}; - return _.isArray(rawElements) ? rawElements.map(cacheElement) : cacheElement(rawElements); +helpers.cacheWebElements = function cacheWebElements (response) { + const toCached = (v) => _.isArray(v) || _.isPlainObject(v) + ? this.cacheWebElements(v) + : v; + + if (_.isArray(response)) { + return response.map(toCached); + } else if (_.isPlainObject(response)) { + const result = {...response, ...(this.cacheWebElement(response))}; + return _.toPairs(result).reduce( + (acc, [key, value]) => { + acc[key] = toCached(value); + return acc; + }, {} + ); + } + return response; }; extensions.findWebElementOrElements = async function findWebElementOrElements (strategy, selector, many, ctx) { @@ -245,7 +258,7 @@ extensions.findWebElementOrElements = async function findWebElementOrElements (s if (many) { return this.cacheWebElements(element); } - if (!element || _.size(element) === 0) { + if (_.isEmpty(element)) { throw new errors.NoSuchElementError(); } return this.cacheWebElements(element);