Merge pull request #12551 from appsmithorg/feature/expose-post-message
feat: Add a field for the post message api exposure
This commit is contained in:
commit
ad601f32fe
|
|
@ -430,6 +430,7 @@ export const CLEAR_INTERVAL = () => `Clear interval`;
|
||||||
export const GET_GEO_LOCATION = () => `Get Geolocation`;
|
export const GET_GEO_LOCATION = () => `Get Geolocation`;
|
||||||
export const WATCH_GEO_LOCATION = () => `Watch Geolocation`;
|
export const WATCH_GEO_LOCATION = () => `Watch Geolocation`;
|
||||||
export const STOP_WATCH_GEO_LOCATION = () => `Stop watching Geolocation`;
|
export const STOP_WATCH_GEO_LOCATION = () => `Stop watching Geolocation`;
|
||||||
|
export const POST_MESSAGE = () => `Post message to a target window`;
|
||||||
|
|
||||||
//js actions
|
//js actions
|
||||||
export const JS_ACTION_COPY_SUCCESS = (actionName: string, pageName: string) =>
|
export const JS_ACTION_COPY_SUCCESS = (actionName: string, pageName: string) =>
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,7 @@ export const ActionType = {
|
||||||
getGeolocation: "appsmith.geolocation.getCurrentPosition",
|
getGeolocation: "appsmith.geolocation.getCurrentPosition",
|
||||||
watchGeolocation: "appsmith.geolocation.watchPosition",
|
watchGeolocation: "appsmith.geolocation.watchPosition",
|
||||||
stopWatchGeolocation: "appsmith.geolocation.clearWatch",
|
stopWatchGeolocation: "appsmith.geolocation.clearWatch",
|
||||||
|
postMessage: "postMessageToTargetWindow",
|
||||||
};
|
};
|
||||||
type ActionType = typeof ActionType[keyof typeof ActionType];
|
type ActionType = typeof ActionType[keyof typeof ActionType];
|
||||||
|
|
||||||
|
|
@ -355,6 +356,8 @@ export enum FieldType {
|
||||||
DELAY_FIELD = "DELAY_FIELD",
|
DELAY_FIELD = "DELAY_FIELD",
|
||||||
ID_FIELD = "ID_FIELD",
|
ID_FIELD = "ID_FIELD",
|
||||||
CLEAR_INTERVAL_ID_FIELD = "CLEAR_INTERVAL_ID_FIELD",
|
CLEAR_INTERVAL_ID_FIELD = "CLEAR_INTERVAL_ID_FIELD",
|
||||||
|
MESSAGE_FIELD = "MESSAGE_FIELD",
|
||||||
|
TARGET_ORIGIN_FIELD = "TARGET_ORIGIN_FIELD",
|
||||||
}
|
}
|
||||||
|
|
||||||
type FieldConfig = {
|
type FieldConfig = {
|
||||||
|
|
@ -622,6 +625,24 @@ const fieldConfigs: FieldConfigs = {
|
||||||
},
|
},
|
||||||
view: ViewTypes.TEXT_VIEW,
|
view: ViewTypes.TEXT_VIEW,
|
||||||
},
|
},
|
||||||
|
[FieldType.MESSAGE_FIELD]: {
|
||||||
|
getter: (value: string) => {
|
||||||
|
return textGetter(value, 0);
|
||||||
|
},
|
||||||
|
setter: (value: string, currentValue: string) => {
|
||||||
|
return textSetter(value, currentValue, 0);
|
||||||
|
},
|
||||||
|
view: ViewTypes.TEXT_VIEW,
|
||||||
|
},
|
||||||
|
[FieldType.TARGET_ORIGIN_FIELD]: {
|
||||||
|
getter: (value: string) => {
|
||||||
|
return textGetter(value, 1);
|
||||||
|
},
|
||||||
|
setter: (value: string, currentValue: string) => {
|
||||||
|
return textSetter(value, currentValue, 1);
|
||||||
|
},
|
||||||
|
view: ViewTypes.TEXT_VIEW,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function renderField(props: {
|
function renderField(props: {
|
||||||
|
|
@ -793,6 +814,8 @@ function renderField(props: {
|
||||||
case FieldType.DELAY_FIELD:
|
case FieldType.DELAY_FIELD:
|
||||||
case FieldType.ID_FIELD:
|
case FieldType.ID_FIELD:
|
||||||
case FieldType.CLEAR_INTERVAL_ID_FIELD:
|
case FieldType.CLEAR_INTERVAL_ID_FIELD:
|
||||||
|
case FieldType.MESSAGE_FIELD:
|
||||||
|
case FieldType.TARGET_ORIGIN_FIELD:
|
||||||
let fieldLabel = "";
|
let fieldLabel = "";
|
||||||
if (fieldType === FieldType.ALERT_TEXT_FIELD) {
|
if (fieldType === FieldType.ALERT_TEXT_FIELD) {
|
||||||
fieldLabel = "Message";
|
fieldLabel = "Message";
|
||||||
|
|
@ -818,6 +841,10 @@ function renderField(props: {
|
||||||
fieldLabel = "Id";
|
fieldLabel = "Id";
|
||||||
} else if (fieldType === FieldType.CLEAR_INTERVAL_ID_FIELD) {
|
} else if (fieldType === FieldType.CLEAR_INTERVAL_ID_FIELD) {
|
||||||
fieldLabel = "Id";
|
fieldLabel = "Id";
|
||||||
|
} else if (fieldType === FieldType.MESSAGE_FIELD) {
|
||||||
|
fieldLabel = "Message";
|
||||||
|
} else if (fieldType === FieldType.TARGET_ORIGIN_FIELD) {
|
||||||
|
fieldLabel = "Target origin";
|
||||||
}
|
}
|
||||||
viewElement = (view as (props: TextViewProps) => JSX.Element)({
|
viewElement = (view as (props: TextViewProps) => JSX.Element)({
|
||||||
label: fieldLabel,
|
label: fieldLabel,
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ import {
|
||||||
NAVIGATE_TO,
|
NAVIGATE_TO,
|
||||||
NO_ACTION,
|
NO_ACTION,
|
||||||
OPEN_MODAL,
|
OPEN_MODAL,
|
||||||
|
POST_MESSAGE,
|
||||||
RESET_WIDGET,
|
RESET_WIDGET,
|
||||||
SET_INTERVAL,
|
SET_INTERVAL,
|
||||||
SHOW_MESSAGE,
|
SHOW_MESSAGE,
|
||||||
|
|
@ -125,6 +126,10 @@ const baseOptions: { label: string; value: string }[] = [
|
||||||
label: createMessage(STOP_WATCH_GEO_LOCATION),
|
label: createMessage(STOP_WATCH_GEO_LOCATION),
|
||||||
value: ActionType.stopWatchGeolocation,
|
value: ActionType.stopWatchGeolocation,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: createMessage(POST_MESSAGE),
|
||||||
|
value: ActionType.postMessage,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const getBaseOptions = (featureFlags: FeatureFlags) => {
|
const getBaseOptions = (featureFlags: FeatureFlags) => {
|
||||||
|
|
@ -373,6 +378,18 @@ function getFieldFromValue(
|
||||||
field: FieldType.CALLBACK_FUNCTION_FIELD,
|
field: FieldType.CALLBACK_FUNCTION_FIELD,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value.indexOf("postMessageToTargetWindow") !== -1) {
|
||||||
|
fields.push(
|
||||||
|
{
|
||||||
|
field: FieldType.MESSAGE_FIELD,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: FieldType.TARGET_ORIGIN_FIELD,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ export enum ActionTriggerType {
|
||||||
WATCH_CURRENT_LOCATION = "WATCH_CURRENT_LOCATION",
|
WATCH_CURRENT_LOCATION = "WATCH_CURRENT_LOCATION",
|
||||||
STOP_WATCHING_CURRENT_LOCATION = "STOP_WATCHING_CURRENT_LOCATION",
|
STOP_WATCHING_CURRENT_LOCATION = "STOP_WATCHING_CURRENT_LOCATION",
|
||||||
CONFIRMATION_MODAL = "CONFIRMATION_MODAL",
|
CONFIRMATION_MODAL = "CONFIRMATION_MODAL",
|
||||||
|
POST_MESSAGE = "POST_MESSAGE",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ActionTriggerFunctionNames: Record<ActionTriggerType, string> = {
|
export const ActionTriggerFunctionNames: Record<ActionTriggerType, string> = {
|
||||||
|
|
@ -37,6 +38,7 @@ export const ActionTriggerFunctionNames: Record<ActionTriggerType, string> = {
|
||||||
[ActionTriggerType.WATCH_CURRENT_LOCATION]: "watchLocation",
|
[ActionTriggerType.WATCH_CURRENT_LOCATION]: "watchLocation",
|
||||||
[ActionTriggerType.STOP_WATCHING_CURRENT_LOCATION]: "stopWatch",
|
[ActionTriggerType.STOP_WATCHING_CURRENT_LOCATION]: "stopWatch",
|
||||||
[ActionTriggerType.CONFIRMATION_MODAL]: "ConfirmationModal",
|
[ActionTriggerType.CONFIRMATION_MODAL]: "ConfirmationModal",
|
||||||
|
[ActionTriggerType.POST_MESSAGE]: "postMessageToTargetWindow",
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RunPluginActionDescription = {
|
export type RunPluginActionDescription = {
|
||||||
|
|
@ -166,6 +168,14 @@ export type ConfirmationModal = {
|
||||||
payload?: Record<string, any>;
|
payload?: Record<string, any>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type PostMessageDescription = {
|
||||||
|
type: ActionTriggerType.POST_MESSAGE;
|
||||||
|
payload: {
|
||||||
|
message: unknown;
|
||||||
|
targetOrigin: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export type ActionDescription =
|
export type ActionDescription =
|
||||||
| RunPluginActionDescription
|
| RunPluginActionDescription
|
||||||
| ClearPluginActionDescription
|
| ClearPluginActionDescription
|
||||||
|
|
@ -182,4 +192,5 @@ export type ActionDescription =
|
||||||
| GetCurrentLocationDescription
|
| GetCurrentLocationDescription
|
||||||
| WatchCurrentLocationDescription
|
| WatchCurrentLocationDescription
|
||||||
| StopWatchingCurrentLocationDescription
|
| StopWatchingCurrentLocationDescription
|
||||||
| ConfirmationModal;
|
| ConfirmationModal
|
||||||
|
| PostMessageDescription;
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ import {
|
||||||
import * as log from "loglevel";
|
import * as log from "loglevel";
|
||||||
import { all, call, put, takeEvery, takeLatest } from "redux-saga/effects";
|
import { all, call, put, takeEvery, takeLatest } from "redux-saga/effects";
|
||||||
import {
|
import {
|
||||||
evaluateArgumentSaga,
|
|
||||||
evaluateAndExecuteDynamicTrigger,
|
evaluateAndExecuteDynamicTrigger,
|
||||||
|
evaluateArgumentSaga,
|
||||||
evaluateSnippetSaga,
|
evaluateSnippetSaga,
|
||||||
setAppVersionOnWorkerSaga,
|
setAppVersionOnWorkerSaga,
|
||||||
} from "sagas/EvaluationsSaga";
|
} from "sagas/EvaluationsSaga";
|
||||||
|
|
@ -36,12 +36,12 @@ import {
|
||||||
logActionExecutionError,
|
logActionExecutionError,
|
||||||
TriggerFailureError,
|
TriggerFailureError,
|
||||||
UncaughtPromiseError,
|
UncaughtPromiseError,
|
||||||
|
UserCancelledActionExecutionError,
|
||||||
} from "sagas/ActionExecution/errorUtils";
|
} from "sagas/ActionExecution/errorUtils";
|
||||||
import {
|
import {
|
||||||
clearIntervalSaga,
|
clearIntervalSaga,
|
||||||
setIntervalSaga,
|
setIntervalSaga,
|
||||||
} from "sagas/ActionExecution/SetIntervalSaga";
|
} from "sagas/ActionExecution/SetIntervalSaga";
|
||||||
import { UserCancelledActionExecutionError } from "sagas/ActionExecution/errorUtils";
|
|
||||||
import {
|
import {
|
||||||
getCurrentLocationSaga,
|
getCurrentLocationSaga,
|
||||||
stopWatchCurrentLocation,
|
stopWatchCurrentLocation,
|
||||||
|
|
@ -49,6 +49,7 @@ import {
|
||||||
} from "sagas/ActionExecution/GetCurrentLocationSaga";
|
} from "sagas/ActionExecution/GetCurrentLocationSaga";
|
||||||
import { requestModalConfirmationSaga } from "sagas/UtilSagas";
|
import { requestModalConfirmationSaga } from "sagas/UtilSagas";
|
||||||
import { ModalType } from "reducers/uiReducers/modalActionReducer";
|
import { ModalType } from "reducers/uiReducers/modalActionReducer";
|
||||||
|
import { postMessageSaga } from "./PostMessageSaga";
|
||||||
|
|
||||||
export type TriggerMeta = {
|
export type TriggerMeta = {
|
||||||
source?: TriggerSource;
|
source?: TriggerSource;
|
||||||
|
|
@ -142,6 +143,9 @@ export function* executeActionTriggers(
|
||||||
throw new UserCancelledActionExecutionError();
|
throw new UserCancelledActionExecutionError();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ActionTriggerType.POST_MESSAGE:
|
||||||
|
yield call(postMessageSaga, trigger.payload, triggerMeta);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
log.error("Trigger type unknown", trigger);
|
log.error("Trigger type unknown", trigger);
|
||||||
throw Error("Trigger type unknown");
|
throw Error("Trigger type unknown");
|
||||||
|
|
|
||||||
60
app/client/src/sagas/ActionExecution/PostMessage.test.ts
Normal file
60
app/client/src/sagas/ActionExecution/PostMessage.test.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { postMessageSaga, executePostMessage } from "./PostMessageSaga";
|
||||||
|
import { spawn } from "redux-saga/effects";
|
||||||
|
import { runSaga } from "redux-saga";
|
||||||
|
|
||||||
|
describe("PostMessageSaga", () => {
|
||||||
|
describe("postMessageSaga function", () => {
|
||||||
|
const generator = postMessageSaga(
|
||||||
|
{
|
||||||
|
message: "hello world",
|
||||||
|
targetOrigin: "https://dev.appsmith.com",
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
it("executes postMessageSaga with the payload and trigger meta", () => {
|
||||||
|
expect(generator.next().value).toStrictEqual(
|
||||||
|
spawn(
|
||||||
|
executePostMessage,
|
||||||
|
{
|
||||||
|
message: "hello world",
|
||||||
|
targetOrigin: "https://dev.appsmith.com",
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be done on next iteration", () => {
|
||||||
|
expect(generator.next().done).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("executePostMessage function", () => {
|
||||||
|
it("calls window.parent with message and target origin", () => {
|
||||||
|
const dispatched: any[] = [];
|
||||||
|
|
||||||
|
const postMessage = jest.spyOn(window.parent, "postMessage");
|
||||||
|
|
||||||
|
runSaga(
|
||||||
|
{
|
||||||
|
dispatch: (action) => dispatched.push(action),
|
||||||
|
},
|
||||||
|
executePostMessage,
|
||||||
|
{
|
||||||
|
message: "hello world",
|
||||||
|
targetOrigin: "https://dev.appsmith.com",
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(postMessage).toHaveBeenCalledWith(
|
||||||
|
"hello world",
|
||||||
|
"https://dev.appsmith.com",
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(dispatched).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
39
app/client/src/sagas/ActionExecution/PostMessageSaga.ts
Normal file
39
app/client/src/sagas/ActionExecution/PostMessageSaga.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { spawn } from "redux-saga/effects";
|
||||||
|
import { PostMessageDescription } from "../../entities/DataTree/actionTriggers";
|
||||||
|
import {
|
||||||
|
logActionExecutionError,
|
||||||
|
TriggerFailureError,
|
||||||
|
} from "sagas/ActionExecution/errorUtils";
|
||||||
|
import { TriggerMeta } from "./ActionExecutionSagas";
|
||||||
|
import { isEmpty } from "lodash";
|
||||||
|
|
||||||
|
export function* postMessageSaga(
|
||||||
|
payload: PostMessageDescription["payload"],
|
||||||
|
triggerMeta: TriggerMeta,
|
||||||
|
) {
|
||||||
|
yield spawn(executePostMessage, payload, triggerMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function* executePostMessage(
|
||||||
|
payload: PostMessageDescription["payload"],
|
||||||
|
triggerMeta: TriggerMeta,
|
||||||
|
) {
|
||||||
|
const { message, targetOrigin } = payload;
|
||||||
|
try {
|
||||||
|
if (targetOrigin === "*") {
|
||||||
|
throw new TriggerFailureError(
|
||||||
|
"Please enter a valid url as targetOrigin. Failing to provide a specific target discloses the data you send to any interested malicious site.",
|
||||||
|
);
|
||||||
|
} else if (isEmpty(targetOrigin)) {
|
||||||
|
throw new TriggerFailureError("Please enter a target origin URL.");
|
||||||
|
} else {
|
||||||
|
window.parent.postMessage(message, targetOrigin, undefined);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logActionExecutionError(
|
||||||
|
(error as Error).message,
|
||||||
|
triggerMeta.source,
|
||||||
|
triggerMeta.triggerPropertyName,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -670,6 +670,11 @@ export const GLOBAL_FUNCTIONS = {
|
||||||
"!doc": "Stop executing a setInterval with id",
|
"!doc": "Stop executing a setInterval with id",
|
||||||
"!type": "fn(id: string) -> void",
|
"!type": "fn(id: string) -> void",
|
||||||
},
|
},
|
||||||
|
postMessageToTargetWindow: {
|
||||||
|
"!doc":
|
||||||
|
"Establish cross-origin communication between Window objects/page and iframes",
|
||||||
|
"!type": "fn(message: unknown, targetOrigin: string)",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getPropsForJSActionEntity = ({
|
export const getPropsForJSActionEntity = ({
|
||||||
|
|
|
||||||
|
|
@ -433,4 +433,162 @@ describe("Add functions", () => {
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Post message to target window works", () => {
|
||||||
|
const targetOrigin = "https://dev.appsmith.com/";
|
||||||
|
|
||||||
|
it("Post message with first argument (message) as a string", () => {
|
||||||
|
const message = "Hello world!";
|
||||||
|
|
||||||
|
expect(
|
||||||
|
dataTreeWithFunctions.postMessageToTargetWindow(message, targetOrigin),
|
||||||
|
).toBe(undefined);
|
||||||
|
|
||||||
|
expect(self.TRIGGER_COLLECTOR).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
payload: {
|
||||||
|
message: "Hello world!",
|
||||||
|
targetOrigin: "https://dev.appsmith.com/",
|
||||||
|
},
|
||||||
|
type: "POST_MESSAGE",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Post message with first argument (message) as undefined", () => {
|
||||||
|
const message = undefined;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
dataTreeWithFunctions.postMessageToTargetWindow(message, targetOrigin),
|
||||||
|
).toBe(undefined);
|
||||||
|
|
||||||
|
expect(self.TRIGGER_COLLECTOR).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
payload: {
|
||||||
|
message: undefined,
|
||||||
|
targetOrigin: "https://dev.appsmith.com/",
|
||||||
|
},
|
||||||
|
type: "POST_MESSAGE",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Post message with first argument (message) as null", () => {
|
||||||
|
const message = null;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
dataTreeWithFunctions.postMessageToTargetWindow(message, targetOrigin),
|
||||||
|
).toBe(undefined);
|
||||||
|
|
||||||
|
expect(self.TRIGGER_COLLECTOR).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
payload: {
|
||||||
|
message: null,
|
||||||
|
targetOrigin: "https://dev.appsmith.com/",
|
||||||
|
},
|
||||||
|
type: "POST_MESSAGE",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Post message with first argument (message) as a number", () => {
|
||||||
|
const message = 1826;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
dataTreeWithFunctions.postMessageToTargetWindow(message, targetOrigin),
|
||||||
|
).toBe(undefined);
|
||||||
|
|
||||||
|
expect(self.TRIGGER_COLLECTOR).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
payload: {
|
||||||
|
message: 1826,
|
||||||
|
targetOrigin: "https://dev.appsmith.com/",
|
||||||
|
},
|
||||||
|
type: "POST_MESSAGE",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Post message with first argument (message) as a boolean", () => {
|
||||||
|
const message = true;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
dataTreeWithFunctions.postMessageToTargetWindow(message, targetOrigin),
|
||||||
|
).toBe(undefined);
|
||||||
|
|
||||||
|
expect(self.TRIGGER_COLLECTOR).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
payload: {
|
||||||
|
message: true,
|
||||||
|
targetOrigin: "https://dev.appsmith.com/",
|
||||||
|
},
|
||||||
|
type: "POST_MESSAGE",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Post message with first argument (message) as an array", () => {
|
||||||
|
const message = [1, 2, 3, [1, 2, 3, [1, 2, 3]]];
|
||||||
|
|
||||||
|
expect(
|
||||||
|
dataTreeWithFunctions.postMessageToTargetWindow(message, targetOrigin),
|
||||||
|
).toBe(undefined);
|
||||||
|
|
||||||
|
expect(self.TRIGGER_COLLECTOR).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
payload: {
|
||||||
|
message: [1, 2, 3, [1, 2, 3, [1, 2, 3]]],
|
||||||
|
targetOrigin: "https://dev.appsmith.com/",
|
||||||
|
},
|
||||||
|
type: "POST_MESSAGE",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Post message with first argument (message) as an object", () => {
|
||||||
|
const message = {
|
||||||
|
key: 1,
|
||||||
|
status: "active",
|
||||||
|
person: {
|
||||||
|
name: "timothee chalamet",
|
||||||
|
},
|
||||||
|
randomArr: [1, 2, 3],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(
|
||||||
|
dataTreeWithFunctions.postMessageToTargetWindow(message, targetOrigin),
|
||||||
|
).toBe(undefined);
|
||||||
|
|
||||||
|
expect(self.TRIGGER_COLLECTOR).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
payload: {
|
||||||
|
message: {
|
||||||
|
key: 1,
|
||||||
|
status: "active",
|
||||||
|
person: {
|
||||||
|
name: "timothee chalamet",
|
||||||
|
},
|
||||||
|
randomArr: [1, 2, 3],
|
||||||
|
},
|
||||||
|
targetOrigin: "https://dev.appsmith.com/",
|
||||||
|
},
|
||||||
|
type: "POST_MESSAGE",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -261,6 +261,16 @@ const DATA_TREE_FUNCTIONS: Record<
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
postMessageToTargetWindow: function(message: unknown, targetOrigin: string) {
|
||||||
|
return {
|
||||||
|
type: ActionTriggerType.POST_MESSAGE,
|
||||||
|
payload: {
|
||||||
|
message,
|
||||||
|
targetOrigin,
|
||||||
|
},
|
||||||
|
executionType: ExecutionType.TRIGGER,
|
||||||
|
};
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const enhanceDataTreeWithFunctions = (
|
export const enhanceDataTreeWithFunctions = (
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user