UNPKG

just-test

Version:
132 lines (111 loc) 4.17 kB
import { SUITE_CONFIG_DEFAULT, TEST_CONFIG_DEFAULT } from '../../../common/constants.js'; import { getTestId, getValidName } from '../../../common/interop-utils.js'; import { runSession } from '../../session-service.js'; import * as serverAPI from '../../server-api-service.js'; // TODO: merge this with browser-session-runner.js export { loadMetadata, execute } let _stateService; /** * runs main flow * - sets up environment (TODO: do the env setup environment based) * - auto executes test session * - signals server upon finalization if non-interactive */ async function execute(metadata, stateService) { _stateService = stateService; // environment setup console.info(`setting up test execution environment...`); stateService.setSessionId(metadata.sessionId); stateService.setEnvironmentId(metadata.id); installTestRegistrationAPIs(); await collectTests(metadata.testPaths, stateService); console.info('... all set'); // auto session execution await runSession(metadata, stateService); } /** * fetches test session definitions */ async function loadMetadata(sesId, envId) { const started = globalThis.performance.now(); console.info(`fetching test session metadata...`); const envConfig = await serverAPI.getSessionMetadata(sesId, envId); console.info(`... metadata fetched (${(globalThis.performance.now() - started).toFixed(1)}ms)`); return envConfig; } /** * installs top level APIs on the top scope object for the registration pass * - getSuite: returns a suite-bound registration APIs */ function installTestRegistrationAPIs() { console.info('installing registration APIs'); Object.defineProperty(globalThis, 'getSuite', { value: getSuite }); } // TODO: on each failure here user should get a visual feedback /** * imports suites/tests metadata * - has a side effect of collecting suites/tests metadata in the state service * * @param {string[]} testsResources - array of paths * @param {object} stateService - state service */ async function collectTests(testsResources, stateService) { const started = globalThis.performance.now(); console.info(`fetching ${testsResources.length} test resource/s...`); for await (const tr of testsResources) { try { await import(`/tests/${tr}`); stateService.getUnSourced().forEach(t => t.source = tr); } catch (e) { console.error(`failed to import '${tr}':`, e); } } console.info(`... test resources fetched (${(globalThis.performance.now() - started).toFixed(1)}ms)`); } // TODO: this and below are registration methods // TODO: move them into suite-runner.js // TODO: on each failure here user should get a visual feedback function getSuite(suiteName, suiteConfig) { const suiteMeta = validateNormalizeSuiteParams(suiteName, suiteConfig); _stateService.obtainSuite(suiteMeta.name, suiteMeta.config); return { test: (testName, testCode, testConfig) => { try { const testMeta = validateNormalizeTestParams(testName, testCode, testConfig); const testId = getTestId(suiteName, testMeta.name); _stateService.addTest(suiteName, testMeta.name, testId, testMeta.code, testMeta.config); } catch (e) { console.error(`failed to register test '${testName} : ${JSON.stringify(testConfig)}':`, e); } } } } function validateNormalizeSuiteParams(sName, config) { const result = {}; // name result.name = getValidName(sName); // configuration if (config !== undefined && typeof config !== 'object') { throw new Error(`suite config, if/when provided, MUST be an object, got '${config}'`); } result.config = Object.freeze(Object.assign({}, SUITE_CONFIG_DEFAULT, config)); return result; } function validateNormalizeTestParams(tName, code, config) { const result = {}; // name result.name = getValidName(tName); // code (validation only) if (!code || typeof code !== 'function') { throw new Error(`test code MUST be a function, got '${code}'`); } // configuration if (config !== undefined && typeof config !== 'object') { throw new Error(`test config, if/when provided, MUST be an object, got '${config}'`); } result.config = Object.freeze(Object.assign({}, TEST_CONFIG_DEFAULT, config)); return result; }