Files
parcer/server/src/workflow-management/utils.ts
2025-01-05 00:39:08 +05:30

107 lines
2.9 KiB
TypeScript

import { Action, ActionType, TagName } from "../types";
/**
* A helper function to get the best selector for the specific user action.
* @param action The user action.
* @returns {string|null}
* @category WorkflowManagement-Selectors
*/
export const getBestSelectorForAction = (action: Action) => {
switch (action.type) {
case ActionType.Click:
case ActionType.Hover:
case ActionType.DragAndDrop: {
const selectors = action.selectors;
if (selectors?.iframeSelector?.full) {
return selectors.iframeSelector.full;
}
if (selectors?.shadowSelector?.full) {
return selectors.shadowSelector.full;
}
// less than 25 characters, and element only has text inside
const textSelector =
selectors?.text?.length != null &&
selectors?.text?.length < 25 &&
action.hasOnlyText
? selectors.generalSelector
: null;
if (action.tagName === TagName.Input) {
return (
selectors.testIdSelector ??
selectors?.id ??
selectors?.formSelector ??
selectors?.accessibilitySelector ??
selectors?.generalSelector ??
selectors?.attrSelector ??
null
);
}
if (action.tagName === TagName.A) {
return (
selectors.testIdSelector ??
selectors?.id ??
selectors?.hrefSelector ??
selectors?.accessibilitySelector ??
selectors?.generalSelector ??
selectors?.attrSelector ??
null
);
}
// Prefer text selectors for spans, ems over general selectors
if (
action.tagName === TagName.Span ||
action.tagName === TagName.EM ||
action.tagName === TagName.Cite ||
action.tagName === TagName.B ||
action.tagName === TagName.Strong
) {
return (
selectors.testIdSelector ??
selectors?.id ??
selectors?.accessibilitySelector ??
selectors?.hrefSelector ??
textSelector ??
selectors?.generalSelector ??
selectors?.attrSelector ??
null
);
}
return (
selectors.testIdSelector ??
selectors?.id ??
selectors?.accessibilitySelector ??
selectors?.hrefSelector ??
selectors?.generalSelector ??
selectors?.attrSelector ??
null
);
}
case ActionType.Input:
case ActionType.Keydown: {
const selectors = action.selectors;
if (selectors?.shadowSelector?.full) {
return selectors.shadowSelector.full;
}
return (
selectors.testIdSelector ??
selectors?.id ??
selectors?.formSelector ??
selectors?.accessibilitySelector ??
selectors?.generalSelector ??
selectors?.attrSelector ??
null
);
}
default:
break;
}
return null;
}