From 8fd3528c4c6fd86f862767da6094c23e12b90962 Mon Sep 17 00:00:00 2001 From: Rohit Rajan Date: Wed, 12 Nov 2025 23:11:15 +0530 Subject: [PATCH 1/4] fix: settings limit capture list --- .../robot/pages/RobotSettingsPage.tsx | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/components/robot/pages/RobotSettingsPage.tsx b/src/components/robot/pages/RobotSettingsPage.tsx index 11832935..cb456e3d 100644 --- a/src/components/robot/pages/RobotSettingsPage.tsx +++ b/src/components/robot/pages/RobotSettingsPage.tsx @@ -152,20 +152,36 @@ export const RobotSettingsPage = ({ handleStart }: RobotSettingsProps) => { }} style={{ marginBottom: "20px" }} /> - {robot.recording.workflow?.[0]?.what?.[0]?.args?.[0]?.limit !== - undefined && ( - - )} + {(() => { + let listCounter = 1; + + return robot.recording.workflow.flatMap((wf, wfIndex) => + wf.what.flatMap((action, actionIndex) => { + const argsWithLimit = action.args?.filter( + (arg: any) => arg && typeof arg === "object" && arg.limit !== undefined + ); + + if (!argsWithLimit?.length) return []; + + return argsWithLimit.map((arg, limitIndex) => { + const labelName = action.name || `List ${listCounter++}`; + return ( + + ); + }); + }) + ); + })()} + Date: Thu, 13 Nov 2025 12:19:39 +0530 Subject: [PATCH 2/4] fix: rm data replication across different actions --- .../classes/Interpreter.ts | 43 ++++++++----------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/server/src/workflow-management/classes/Interpreter.ts b/server/src/workflow-management/classes/Interpreter.ts index 71cac8b7..9291091e 100644 --- a/server/src/workflow-management/classes/Interpreter.ts +++ b/server/src/workflow-management/classes/Interpreter.ts @@ -550,37 +550,26 @@ export class WorkflowInterpreter { }, serializableCallback: async (data: any) => { try { - if (!data || typeof data !== "object") return; + if (!this.currentActionType || !this.currentActionName) return; - if (!this.currentActionType && Array.isArray(data) && data.length > 0) { - const first = data[0]; - if (first && Object.keys(first).some(k => k.toLowerCase().includes("label") || k.toLowerCase().includes("text"))) { - this.currentActionType = "scrapeSchema"; - } - } + let typeKey = this.currentActionType; + let actionName = this.currentActionName; - let typeKey = this.currentActionType || "unknown"; + let subtree = + typeKey === "scrapeList" + ? data?.scrapeList + : typeKey === "scrapeSchema" + ? data?.scrapeSchema + : null; - if (this.currentActionType === "scrapeList") { - typeKey = "scrapeList"; - } else if (this.currentActionType === "scrapeSchema") { - typeKey = "scrapeSchema"; - } + if (!subtree) return; - if (this.currentActionType === "scrapeList" && data.scrapeList) { - data = data.scrapeList; - } else if (this.currentActionType === "scrapeSchema" && data.scrapeSchema) { - data = data.scrapeSchema; - } - - let actionName = this.currentActionName || ""; if (typeKey === "scrapeList") { - actionName = this.getUniqueActionName(typeKey, this.currentActionName); + actionName = this.getUniqueActionName(typeKey, actionName); } - const flattened = Array.isArray(data) - ? data - : (data?.List ?? (data && typeof data === 'object' ? Object.values(data).flat?.() ?? data : [])); + const values = Object.values(subtree); + const flattened = values.flat(); if (!this.serializableDataByType[typeKey]) { this.serializableDataByType[typeKey] = {}; @@ -588,7 +577,9 @@ export class WorkflowInterpreter { this.serializableDataByType[typeKey][actionName] = flattened; - await this.persistDataToDatabase(typeKey, { [actionName]: flattened }); + await this.persistDataToDatabase(typeKey, { + [actionName]: flattened, + }); this.socket.emit("serializableCallback", { type: typeKey, @@ -599,7 +590,7 @@ export class WorkflowInterpreter { this.currentActionType = null; this.currentActionName = null; } catch (err: any) { - logger.log('error', `serializableCallback handler failed: ${err.message}`); + logger.log("error", `serializableCallback failed: ${err.message}`); } }, binaryCallback: async (payload: { name: string; data: Buffer; mimeType: string }) => { From 288614bdcf84362ca44a94418e5560484847b78a Mon Sep 17 00:00:00 2001 From: Rohit Rajan Date: Thu, 13 Nov 2025 12:43:47 +0530 Subject: [PATCH 3/4] fix: use fresh button on clicking --- maxun-core/src/interpret.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/maxun-core/src/interpret.ts b/maxun-core/src/interpret.ts index fdc31cdc..724f3402 100644 --- a/maxun-core/src/interpret.ts +++ b/maxun-core/src/interpret.ts @@ -1169,7 +1169,7 @@ export default class Interpreter extends EventEmitter { }).catch(e => { throw e; }), - button.click() + page.locator(workingSelector).first().click() ]); debugLog("Navigation successful after regular click"); await page.waitForTimeout(2000); @@ -1184,17 +1184,17 @@ export default class Interpreter extends EventEmitter { }).catch(e => { throw e; }), - button.dispatchEvent('click') + page.locator(workingSelector).first().dispatchEvent('click') ]); debugLog("Navigation successful after dispatch event"); await page.waitForTimeout(2000); paginationSuccess = true; } catch (dispatchNavError) { try { - await button.click(); + await page.locator(workingSelector).first().click(); await page.waitForTimeout(2000); } catch (clickError) { - await button.dispatchEvent('click'); + await page.locator(workingSelector).first().dispatchEvent('click'); await page.waitForTimeout(2000); } } From 77f2a87bdc75ed5e44822cf35f7acebe5f4954fc Mon Sep 17 00:00:00 2001 From: Karishma Shukla Date: Tue, 18 Nov 2025 15:48:19 +0530 Subject: [PATCH 4/4] chore: alts Added a comparison to other web scraping tools. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f56e4564..48b1bcc1 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@

Maxun lets you train a robot in 2 minutes and scrape the web on auto-pilot. Web data extraction doesn't get easier than this! +
Maxun is the open-source alternative to BrowseAI, Octoparse and likes.