Upload files to "qkf"
This commit is contained in:
135
qkf/loaders.js
Normal file
135
qkf/loaders.js
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* qkf/loaders.js
|
||||
* Loads your existing (non-standard) JS files without modifying them:
|
||||
* - pages/*.js may contain "export const X = ..." and use "By"
|
||||
* - step-definitons/*.js may call global WHEN/AND/etc and use qkf/pages globals
|
||||
*/
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const vm = require("vm");
|
||||
|
||||
function readText(p) {
|
||||
return fs.readFileSync(p, "utf-8");
|
||||
}
|
||||
|
||||
function listJsFiles(dir) {
|
||||
if (!fs.existsSync(dir)) return [];
|
||||
return fs
|
||||
.readdirSync(dir)
|
||||
.filter((f) => f.toLowerCase().endsWith(".js"))
|
||||
.map((f) => path.join(dir, f))
|
||||
.sort();
|
||||
}
|
||||
|
||||
function createBy() {
|
||||
// Try selenium-webdriver's By. If not present, return a safe fallback.
|
||||
try {
|
||||
const { By } = require("selenium-webdriver");
|
||||
return By;
|
||||
} catch {
|
||||
return {
|
||||
id: (v) => ({ using: "id", value: v }),
|
||||
xpath: (v) => ({ using: "xpath", value: v }),
|
||||
css: (v) => ({ using: "css", value: v }),
|
||||
name: (v) => ({ using: "name", value: v }),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms tiny ESM snippets into CommonJS exports:
|
||||
* - "export const Login = ..." -> "exports.Login = ..."
|
||||
* Only handles the patterns present in your zip (simple export const).
|
||||
*/
|
||||
function transformEsmExportsToCjs(src) {
|
||||
return String(src)
|
||||
.replace(/^\s*export\s+const\s+([A-Za-z_$][\w$]*)\s*=\s*/gm, "exports.$1 = ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a JS file in a vm context and returns module.exports/exports.
|
||||
*/
|
||||
function runFileInVm(filePath, { injectedGlobals = {}, filenameLabel } = {}) {
|
||||
const codeRaw = readText(filePath);
|
||||
const code = transformEsmExportsToCjs(codeRaw);
|
||||
|
||||
const module = { exports: {} };
|
||||
const exports = module.exports;
|
||||
|
||||
const sandbox = {
|
||||
module,
|
||||
exports,
|
||||
require,
|
||||
__filename: filePath,
|
||||
__dirname: path.dirname(filePath),
|
||||
console,
|
||||
|
||||
// ✅ Node globals your step files may rely on
|
||||
process,
|
||||
Buffer,
|
||||
setTimeout,
|
||||
clearTimeout,
|
||||
setInterval,
|
||||
clearInterval,
|
||||
|
||||
...injectedGlobals,
|
||||
};
|
||||
|
||||
vm.createContext(sandbox);
|
||||
|
||||
const wrapped = `(function(){\n${code}\n})();`;
|
||||
vm.runInContext(wrapped, sandbox, {
|
||||
filename: filenameLabel || filePath,
|
||||
displayErrors: true,
|
||||
});
|
||||
|
||||
return sandbox.module.exports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all page selector modules from pagesDir.
|
||||
* Returns a flat object like { Login: {...}, OtherPage: {...} }
|
||||
*/
|
||||
function loadPages(pagesDir) {
|
||||
const By = createBy();
|
||||
const files = listJsFiles(pagesDir);
|
||||
|
||||
const pages = {};
|
||||
for (const f of files) {
|
||||
const exp = runFileInVm(f, { injectedGlobals: { By }, filenameLabel: `pages:${path.basename(f)}` });
|
||||
Object.assign(pages, exp);
|
||||
}
|
||||
return pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all step-definition modules from stepDefsDir and executes them.
|
||||
* Your current step file just calls WHEN/AND directly at top-level, so executing it is enough.
|
||||
*/
|
||||
function loadStepDefinitions(stepDefsDir, registry, { qkf, pages } = {}) {
|
||||
const files = listJsFiles(stepDefsDir);
|
||||
|
||||
for (const f of files) {
|
||||
runFileInVm(f, {
|
||||
filenameLabel: `steps:${path.basename(f)}`,
|
||||
injectedGlobals: {
|
||||
// bind DSL to registry
|
||||
WHEN: registry.WHEN,
|
||||
AND: registry.AND,
|
||||
THEN: registry.THEN,
|
||||
GIVEN: registry.GIVEN,
|
||||
BUT: registry.BUT,
|
||||
|
||||
// inject the things your step files expect
|
||||
qkf,
|
||||
...pages, // makes "Login" available directly if they do "Login.username"
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
loadPages,
|
||||
loadStepDefinitions,
|
||||
};
|
||||
Reference in New Issue
Block a user