@ptrthomas I see there is a configuration script loading sequence in the ScenarioContext.
It is a little bit complicated sequence I know.
If I make a modification CallContext to carry callContext.configurationContent String and carry to ScenarioContext and let it evaluate during Script.callAndUpdateConfigAndAlsoVarsIfMapReturned sequence. is that kind of modification you mind seeing it? If you don't mind, I can work on it and do pull request. maybe take out configuration loading logic and provide some kind of static factory..
public ScenarioContext(FeatureContext featureContext, CallContext call) {
this.featureContext = featureContext; // make sure references below to env.env use the updated one
logger = featureContext.logger;
callDepth = call.callDepth;
reuseParentContext = call.reuseParentContext;
executionHook = call.executionHook;
perfMode = call.perfMode;
tags = call.getTags().getTags();
tagValues = call.getTags().getTagValues();
scenarioInfo = call.getScenarioInfo();
if (reuseParentContext) {
parentContext = call.context;
vars = call.context.vars; // shared context !
config = call.context.config;
rootFeatureContext = call.context.rootFeatureContext;
driver = call.context.driver;
webSocketClients = call.context.webSocketClients;
} else if (call.context != null) {
parentContext = call.context;
// complex objects like JSON and XML are "global by reference" TODO
vars = call.context.vars.copy(false);
config = new HttpConfig(call.context.config);
rootFeatureContext = call.context.rootFeatureContext;
} else {
parentContext = null;
vars = new ScriptValueMap();
config = new HttpConfig();
config.setClientClass(call.httpClientClass);
rootFeatureContext = featureContext;
}
client = HttpClient.construct(config, this);
bindings = new ScriptBindings(this);
if (call.context == null && call.evalKarateConfig) {
// base config is only looked for in the classpath
try {
Script.callAndUpdateConfigAndAlsoVarsIfMapReturned(false, ScriptBindings.READ_KARATE_CONFIG_BASE, null, this);
} catch (Exception e) {
if (e instanceof KarateFileNotFoundException) {
logger.trace("skipping 'classpath:karate-base.js': {}", e.getMessage());
} else {
throw new RuntimeException("evaluation of 'classpath:karate-base.js' failed", e);
}
}
String configDir = System.getProperty(ScriptBindings.KARATE_CONFIG_DIR);
String configScript = ScriptBindings.readKarateConfigForEnv(true, configDir, null);
try {
Script.callAndUpdateConfigAndAlsoVarsIfMapReturned(false, configScript, null, this);
} catch (Exception e) {
if (e instanceof KarateFileNotFoundException) {
logger.warn("skipping bootstrap configuration: {}", e.getMessage());
} else {
throw new RuntimeException("evaluation of '" + ScriptBindings.KARATE_CONFIG_JS + "' failed", e);
}
}
if (featureContext.env != null) {
configScript = ScriptBindings.readKarateConfigForEnv(false, configDir, featureContext.env);
try {
Script.callAndUpdateConfigAndAlsoVarsIfMapReturned(false, configScript, null, this);
} catch (Exception e) {
if (e instanceof KarateFileNotFoundException) {
logger.trace("skipping bootstrap configuration for env: {} - {}", featureContext.env, e.getMessage());
} else {
throw new RuntimeException("evaluation of 'karate-config-" + featureContext.env + ".js' failed", e);
}
}
}
}
//String content of Configuration loading condition here.
if (call.callArg != null) { // if call.reuseParentContext is true, arg will clobber parent context
for (Map.Entry<String, Object> entry : call.callArg.entrySet()) {
vars.put(entry.getKey(), entry.getValue());
}
vars.put(Script.VAR_ARG, call.callArg);
vars.put(Script.VAR_LOOP, call.loopIndex);
} else if (call.context != null) {
vars.put(Script.VAR_ARG, ScriptValue.NULL);
vars.put(Script.VAR_LOOP, -1);
}
logger.trace("karate context init - initial properties: {}", vars);
}
if you just need to inject extra custom variables I propose this. the CallContext has a callArg Map - and all key-values will be injected like you see above at the end. maybe that will suffice for you ? even if you have a JS function, you should be able to eval it and get the result Map
yes this code is already complicated - and runs before every Scenario and Examples row
oh ok, I did not think about that. eval(configurationContent) could do the job.
thanks