Merge pull request #41 from amhsirak/develop

feat: display selected element information for decision modal
This commit is contained in:
Karishma Shukla
2024-09-23 18:00:10 +05:30
committed by GitHub
2 changed files with 39 additions and 9 deletions

View File

@@ -23,6 +23,8 @@ interface PersistedGeneratedData {
lastUsedSelector: string; lastUsedSelector: string;
lastIndex: number | null; lastIndex: number | null;
lastAction: string; lastAction: string;
lastUsedSelectorTagName: string;
lastUsedSelectorInnerText: string;
} }
interface MetaData { interface MetaData {
@@ -97,6 +99,8 @@ export class WorkflowGenerator {
lastUsedSelector: '', lastUsedSelector: '',
lastIndex: null, lastIndex: null,
lastAction: '', lastAction: '',
lastUsedSelectorTagName: '',
lastUsedSelectorInnerText: '',
} }
/** /**
@@ -299,6 +303,22 @@ export class WorkflowGenerator {
await this.addPairToWorkflowAndNotifyClient(pair, page); await this.addPairToWorkflowAndNotifyClient(pair, page);
}; };
/**
* Returns tag name and text content for the specified selector
* used in customAction for decision modal
*/
private async getLastUsedSelectorInfo(page: Page, selector: string) {
const elementHandle = await page.$(selector);
if (elementHandle) {
const tagName = await elementHandle.evaluate(el => (el as HTMLElement).tagName);
// TODO: based on tagName, send data. Always innerText won't hold true. For now, can roll.
const innerText = await elementHandle.evaluate(el => (el as HTMLElement).innerText);
return { tagName, innerText };
}
return { tagName: '', innerText: '' };
}
/** /**
* Generates a pair for the custom action event. * Generates a pair for the custom action event.
* @param action The type of the custom action. * @param action The type of the custom action.
@@ -315,11 +335,15 @@ export class WorkflowGenerator {
} }
if (this.generatedData.lastUsedSelector) { if (this.generatedData.lastUsedSelector) {
const elementInfo = await this.getLastUsedSelectorInfo(page, this.generatedData.lastUsedSelector);
this.socket.emit('decision', { this.socket.emit('decision', {
pair, actionType: 'customAction', pair, actionType: 'customAction',
lastData: { lastData: {
selector: this.generatedData.lastUsedSelector, selector: this.generatedData.lastUsedSelector,
action: this.generatedData.lastAction, action: this.generatedData.lastAction,
tagName: elementInfo.tagName,
innerText: elementInfo.innerText,
} }
}); });
} else { } else {
@@ -486,7 +510,7 @@ export class WorkflowGenerator {
const selectorBasedOnCustomAction = (this.getList === true) const selectorBasedOnCustomAction = (this.getList === true)
? await getNonUniqueSelectors(page, coordinates) ? await getNonUniqueSelectors(page, coordinates)
: await getSelectors(page, coordinates); : await getSelectors(page, coordinates);
const bestSelector = getBestSelectorForAction( const bestSelector = getBestSelectorForAction(
{ {
type: action, type: action,

View File

@@ -28,9 +28,11 @@ export const InterpretationButtons = ({ enableStepping }: InterpretationButtonsP
pair: WhereWhatPair | null, pair: WhereWhatPair | null,
actionType: string, actionType: string,
selector: string, selector: string,
tagName: string,
innerText: string,
action: string, action: string,
open: boolean open: boolean
}>({ pair: null, actionType: '', selector: '', action: '', open: false }); }>({ pair: null, actionType: '', selector: '', action: '', tagName: '', innerText: '', open: false });
const { socket } = useSocketStore(); const { socket } = useSocketStore();
const { notify } = useGlobalInfoStore(); const { notify } = useGlobalInfoStore();
@@ -48,14 +50,16 @@ export const InterpretationButtons = ({ enableStepping }: InterpretationButtonsP
const decisionHandler = useCallback( const decisionHandler = useCallback(
({ pair, actionType, lastData } ({ pair, actionType, lastData }
: { pair: WhereWhatPair | null, actionType: string, lastData: { selector: string, action: string } }) => { : { pair: WhereWhatPair | null, actionType: string, lastData: { selector: string, action: string, tagName: string, innerText: string } }) => {
const { selector, action } = lastData; const { selector, action, tagName, innerText } = lastData;
setDecisionModal((prevState) => { setDecisionModal((prevState) => {
return { return {
pair, pair,
actionType, actionType,
selector, selector,
action, action,
tagName,
innerText,
open: true, open: true,
} }
}) })
@@ -64,7 +68,7 @@ export const InterpretationButtons = ({ enableStepping }: InterpretationButtonsP
const handleDecision = (decision: boolean) => { const handleDecision = (decision: boolean) => {
const { pair, actionType } = decisionModal; const { pair, actionType } = decisionModal;
socket?.emit('decision', { pair, actionType, decision }); socket?.emit('decision', { pair, actionType, decision });
setDecisionModal({ pair: null, actionType: '', selector: '', action: '', open: false }); setDecisionModal({ pair: null, actionType: '', selector: '', action: '', tagName: '', innerText: '', open: false });
} }
const handleDescription = () => { const handleDescription = () => {
@@ -73,12 +77,14 @@ export const InterpretationButtons = ({ enableStepping }: InterpretationButtonsP
return ( return (
<React.Fragment> <React.Fragment>
<Typography> <Typography>
Do you want to use the previously recorded selector Do you want to use your previous selection as a condition for performing this action?
as a where condition for matching the action?
</Typography> </Typography>
<Box style={{ marginTop: '4px' }}> <Box style={{ marginTop: '4px' }}>
[previous action: <b>{decisionModal.action}</b>] <Typography>Your previous action was:
<pre>{decisionModal.selector}</pre> <b>{decisionModal.action.charAt(0).toUpperCase() + decisionModal.action.slice(1)} </b>,
on an element with text
<b>{decisionModal.innerText} </b>
</Typography>
</Box> </Box>
</React.Fragment>); </React.Fragment>);
default: return null; default: return null;