Description of the problem:
When developing or testing (e.g. with Cypress) a BAP based application, you often face the problem that you have to prepare a certain app state in order to carry out certain actions.
This happens for example if you develop or test features that are contained deeply in your app and can only be accessed if a certain state is prepared.
Until now we did these preparations mostly manually or by executing certain steps in our tests.
Solution idea:
Since the BAP uses redux for state containment, we had the idea that we could just rehydrate the redux store in order to get our app into a certain state without executing any preparation steps.
The behaviour can in principle be testet using the redux browser devtools, but certain kernel objects in the state lead to problems.
Question:
My question is: Is there somebody who has tried or is using this approach for a BAP application?
Yes, I modified the Redux Store Configuration in some customer projects. It’s been some months since I used it. Basically you need to setup a custom serializer that handles some object methods concerning Kernel validation code (this naturally breaks Redux contract of just putting data in the store, but Kernel needs it…)
I post a follow-up with a description on how to do it asap.
Hi @rolf-smooth-qubit,
to have a general overview on how to implement serializer with @redux-devtools/extension please have a look into the dedicated documentation: redux-devtools/Arguments.md at main · reduxjs/redux-devtools · GitHub.
A specific implementation for A12 Kernels GeneratedScriptCodeAccessor will follow here:
First of all implement @redux-devtools/extension into your app setup configuration (when using template its the appsetup.ts).
// appsetup.ts
import { composeWithDevToolsDevelopmentOnly } from "@redux-devtools/extension";
import { devToolsOptions } from "./options";
ApplicationFactories.createApplicationSetup({
// ...
// e.g. only for dev by using **@redux-devtools/extension** helper functions. see context https://github.com/reduxjs/redux-devtools/tree/main/extension#14-using-in-production
composeEnhancer: composeWithDevToolsDevelopmentOnly(devToolsOptions)
// ...
});
Then define the necessary options. You have to implement the before mentioned serialize option.
// options.ts
import { EnhancerOptions } from "@redux-devtools/extension";
import { GeneratedCodeAccessorFactory } from "@com.mgmtp.a12.kernel/kernel-md-facade/lib/main/js/facade";
import { GeneratedScriptCodeAccessor } from "@com.mgmtp.a12.kernel/kernel-md-facade/lib/main/js/internal/GeneratedScriptCodeAccessor";
export const devToolsOptions: EnhancerOptions = {
serialize: {
replacer,
reviver,
},
}
// used for both actions and states stringify
function replacer(key: any, value: any) {
if (value instanceof GeneratedScriptCodeAccessor) {
return {
script: value["script"],
__serializedType__: "GeneratedScriptCodeAccessor",
};
} else {
return value;
}
}
// used for parsing the imported actions and states
function reviver(key: any, value: any): any {
if (typeof value === "object" && value !== null && "__serializedType__" in value) {
switch (value.__serializedType__) {
case "GeneratedScriptCodeAccessor":
return new GeneratedCodeAccessorFactory().createScriptAccessor(value.script);
default:
return value;
}
} else {
return value;
}
}
Keep in mind there is an existing issue in @redux-devtools/extension that prevents reviver from beeing called if immutable flag for option is not somehow set (Impossible to call reviver without immutable prop set · Issue #1115 · reduxjs/redux-devtools · GitHub).
To workarround that issue simply add an empty immutable object entry inside the serialize prop (beside reviver and replacer).
const fixedOptions = {
...devToolsOptions,
serialize: {
immutable: {},
...devToolsOptions.serialize,
}
}
Additional information
if you like to decrease the size of your runtime state representation inside the redux devtools (e.g. because of performance issues when working with dev tools) have a look into sanitizers redux-devtools/Arguments.md at main · reduxjs/redux-devtools · GitHub