appium-remote-debugger
Version:
Appium proxy for Remote Debugger protocol
96 lines • 3.86 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAtom = getAtom;
exports.getScriptForAtom = getScriptForAtom;
const support_1 = require("@appium/support");
const node_path_1 = __importDefault(require("node:path"));
const lodash_1 = __importDefault(require("lodash"));
const logger_1 = require("./logger");
const utils_1 = require("./utils");
const ATOMS_CACHE = {};
/**
* Converts a value to a JSON string, handling undefined values specially.
*
* @param obj - The value to stringify.
* @returns A JSON string representation of the value, or 'undefined' if the value is undefined.
*/
function atomsStringify(obj) {
if (typeof obj === 'undefined') {
return 'undefined';
}
return JSON.stringify(obj);
}
/**
* Loads an atom script from the atoms directory and caches it.
* If the atom has been loaded before, returns the cached version.
*
* @param atomName - The name of the atom to load (without the .js extension).
* @returns A promise that resolves to the atom script as a Buffer.
* @throws Error if the atom file cannot be loaded.
*/
async function getAtom(atomName) {
// check if we have already loaded and cached this atom
if (!lodash_1.default.has(ATOMS_CACHE, atomName)) {
const atomFileName = node_path_1.default.resolve((0, utils_1.getModuleRoot)(), 'atoms', `${atomName}.js`);
try {
ATOMS_CACHE[atomName] = await support_1.fs.readFile(atomFileName);
}
catch {
throw new Error(`Unable to load Atom '${atomName}' from file '${atomFileName}'`);
}
}
return ATOMS_CACHE[atomName];
}
/**
* Wraps a script to execute it within a specific frame context.
* Uses the get_element_from_cache atom to access the frame element.
*
* @param script - The script to wrap.
* @param frame - The frame identifier to execute the script in.
* @returns A promise that resolves to the wrapped script string.
*/
async function wrapScriptForFrame(script, frame) {
logger_1.log.debug(`Wrapping script for frame '${frame}'`);
const elFromCache = await getAtom('get_element_from_cache');
return (`(function (window) { var document = window.document; ` +
`return (${script}); })((${elFromCache.toString('utf8')})(${atomsStringify(frame)}))`);
}
/**
* Generates a complete script string for executing a Selenium atom.
* Handles frame contexts and optional async callbacks.
*
* @param atom - The name of the atom to execute.
* @param args - Arguments to pass to the atom function. Defaults to empty array.
* @param frames - Array of frame identifiers to execute the atom in nested frames.
* Defaults to empty array (executes in default context).
* @param asyncCallBack - Optional callback function string for async execution.
* If provided, the atom will be called with this callback.
* @returns A promise that resolves to the complete script string ready for execution.
*/
async function getScriptForAtom(atom, args = [], frames = [], asyncCallBack = null) {
const atomSrc = (await getAtom(atom)).toString('utf8');
let script;
if (frames.length > 0) {
script = atomSrc;
for (const frame of frames) {
script = await wrapScriptForFrame(script, frame);
}
}
else {
logger_1.log.debug(`Executing '${atom}' atom in default context`);
script = `(${atomSrc})`;
}
// add the arguments, as strings
args = args.map(atomsStringify);
if (asyncCallBack) {
script += `(${args.join(',')}, ${asyncCallBack}, true)`;
}
else {
script += `(${args.join(',')})`;
}
return script;
}
//# sourceMappingURL=atoms.js.map