// qkf/qkf.js let _impl = null; // Tracks pending async actions triggered inside a step definition let _pending = null; function requireImpl() { if (!_impl) { throw new Error("QKF Selenium is not initialized. Did you call runtime.beforeEachTest()?"); } return _impl; } function setImpl(impl) { _impl = impl; } function clearImpl() { _impl = null; _pending = null; } /** * Called by the registry before executing a step-definition. * Resets the pending promise list. */ function __beginStep() { _pending = []; } /** * Called by the registry after the step-definition returns. * Waits for all async actions triggered during the step. */ async function __endStep() { const pending = _pending || []; _pending = null; if (!pending.length) return; // Ensure we surface failures to Mocha const results = await Promise.allSettled(pending); const rejected = results.filter((r) => r.status === "rejected"); if (rejected.length) { // Throw the first error (keeps stack readable) throw rejected[0].reason; } } /** * Track a promise so it can be awaited even if caller forgets `await`. */ function track(p) { if (_pending && p && typeof p.then === "function") _pending.push(p); return p; } const qkf = { setImpl, clearImpl, // internal hooks used by registry __beginStep, __endStep, // public api used by step-definitions goto(url) { return track(requireImpl().goto(url)); }, enterValue(locator, value) { return track(requireImpl().enterValue(locator, value)); }, click(locator) { return track(requireImpl().click(locator)); }, waitVisible(locator, timeoutMs) { return track(requireImpl().waitVisible(locator, timeoutMs)); }, getText(locator, timeoutMs) { return track(requireImpl().getText(locator, timeoutMs)); }, screenshotBase64() { return track(requireImpl().screenshotBase64()); }, quit() { return track(requireImpl().quit()); } }; module.exports = qkf;