// qkf/runtime.js const path = require("path"); const qkf = require("./qkf"); const { createStepRegistry } = require("./stepRegistry"); const { loadPages, loadStepDefinitions } = require("./loaders"); const { createDriver } = require("./driverFactory"); const { createQkfSelenium } = require("./selenium/qkfSelenium"); function createRuntime({ rootDir } = {}) { const base = rootDir || process.cwd(); const pagesDir = path.resolve(base, "pages"); const stepDefsDir = path.resolve(base, "step-definitons"); const pages = loadPages(pagesDir); // registry is global (step defs registered once) const registry = createStepRegistry({ qkf, pages }); // registers steps by executing the user's files in vm loadStepDefinitions(stepDefsDir, registry, { qkf, pages }); async function beforeEachTest() { const driver = await createDriver(); const impl = createQkfSelenium(driver); qkf.setImpl(impl); return { driver }; } async function afterEachTest({ test, allureAttachment } = {}) { try { if (test && test.state === "failed") { // screenshot as base64 png const pngBase64 = await qkf.screenshotBase64(); if (typeof allureAttachment === "function") { // attach raw PNG buffer to Allure const buf = Buffer.from(pngBase64, "base64"); await allureAttachment("Screenshot (failure)", buf, "image/png"); } } } catch (e) { // don't crash teardown for reporting failures // console.warn("[qkf] failed to attach screenshot:", e?.message || e); } finally { try { await qkf.quit(); } catch {} qkf.clearImpl(); } } return { qkf, pages, registry, beforeEachTest, afterEachTest }; } module.exports = { createRuntime };