阶段0-基线与护栏: 修复不可移植/抖动测试全绿(341过), vitest串行执行防桌面竞争, 新增运行时能力注册快照(909个id)

This commit is contained in:
yu 2026-11-04 11:53:41 +08:00 committed by trae-solo-agent
parent f35f0ac979
commit 4139400dbd
9 changed files with 1030 additions and 36 deletions

View File

@ -12,6 +12,7 @@
"preview": "electron-vite preview",
"typecheck": "tsc --noEmit -p tsconfig.json",
"catalog": "node scripts/build-catalog.mjs",
"snapshot": "vitest run scripts/capability-snapshot.test.ts",
"package": "node scripts/package.mjs",
"test": "vitest run",
"test:e2e": "node scripts/demo-e2e.mjs"

View File

@ -0,0 +1,915 @@
{
"generatedAt": "2026-11-04T03:53:23.689Z",
"count": 909,
"ids": [
"App_GetPid",
"App_GetPids",
"App_Kill",
"App_KillV1",
"App_Run",
"App_Start",
"Array_Reshape2Dim",
"Basic_BusinessOrderCount",
"Basic_Clone",
"Basic_ConvertBool",
"Basic_ConvertInt",
"Basic_ConvertNumber",
"Basic_ConvertString",
"Basic_DataTypeConversion",
"Basic_DebugOutput",
"Basic_Delay",
"Basic_Delay_V1",
"Basic_Delay_V2",
"Basic_Dodecryption",
"Basic_GetProcessInfo",
"Basic_IsArray",
"Basic_IsDictionary",
"Basic_IsNull",
"Basic_IsNumber",
"Basic_JudgeDataType",
"Basic_RandomInt",
"Basic_Rnd",
"Basic_SetVariable",
"Basic_SetVariable_V1",
"Basic_StringToNum",
"Basic_Type",
"Bivartable_ColumnOperationDf",
"Bivartable_CreateDf",
"Bivartable_CreateDfV1",
"Bivartable_DelDfColRow",
"Bivartable_DeleteDuplicateRow",
"Bivartable_DfWriteToFile",
"Bivartable_DoCal",
"Bivartable_DoCreate",
"Bivartable_DoFilter",
"Bivartable_DoJoint",
"Bivartable_DoMerge",
"Bivartable_DoOpenExcel",
"Bivartable_DoSave",
"Bivartable_DoSort",
"Bivartable_Dtype",
"Bivartable_FilterDf",
"Bivartable_GetAvgValue",
"Bivartable_GetMaxValue",
"Bivartable_GetMinValue",
"Bivartable_GetSumValue",
"Bivartable_HandleDfMissValue",
"Bivartable_InsertDfData",
"Bivartable_MergeDf",
"Bivartable_ModifyColName",
"Bivartable_ModifyDfName",
"Bivartable_PivotDf",
"Bivartable_ReadDfData",
"Bivartable_ReadDfData_V1",
"Bivartable_ReadDfIndexColumns",
"Bivartable_ReadDfShape",
"Bivartable_ReadTable",
"Bivartable_SortDf",
"Bivartable_SpliceColData",
"Bivartable_SummaryCalculationDf",
"Bivartable_WriteDfData",
"Bivartable_WriteTable",
"CSV_Read",
"CSV_ReadNew",
"CSV_Write",
"CSV_WriteNew",
"CV_GetText",
"CV_MouseClick",
"CV_MouseHover",
"CV_SetText",
"Clipboard_ClearClipboard",
"Clipboard_GetText",
"Clipboard_GetTextV1",
"Clipboard_SaveImage",
"Clipboard_SaveImageV1",
"Clipboard_SetImage",
"Clipboard_SetImageV1",
"Clipboard_SetText",
"Clipboard_SetTextV1",
"Collection_Add",
"Collection_Count",
"Collection_Create",
"Collection_HasItem",
"Collection_Remove",
"CustomConfig_GetConfig",
"DataService_AIGenTxt",
"DataService_AgentCall",
"DataService_ChatBot",
"DataService_Correct",
"DataService_Diff",
"DataService_KeyWord",
"DataService_LargeModel",
"DataService_Review",
"DataService_TextComparison",
"DataService_WorkingDay",
"DataService_ZBrain",
"Database_AllSQLQuery",
"Database_AllSQLQuery_V1",
"Database_BatchInsertExecute",
"Database_BatchSQLExecute",
"Database_CloseDBConnect",
"Database_DBConnect",
"Database_SQLExecute",
"Database_SingleSQLQuery",
"Databook_Clear",
"Databook_DeleteColumn",
"Databook_DeleteRow",
"Databook_Export",
"Databook_GetColumnInfo",
"Databook_GetRowAndColCount",
"Databook_Import",
"Databook_ReadContent",
"Databook_SetColumnInfo",
"Databook_WriteContent",
"Dialog_CsInputBox",
"Dialog_CsMsgBox",
"Dialog_GetConfig",
"Dialog_GetConfigV1",
"Dialog_GetConfigV2",
"Dialog_GetConfigV3",
"Dialog_GetConfigV4",
"Dialog_GetConfigV5",
"Dialog_GetConfigV6",
"Dialog_GetConfigV7",
"Dialog_GetConfigV8",
"Dialog_InputBox",
"Dialog_MsgBox",
"Dialog_Notice",
"Dialog_Notice_V1",
"Dialog_Notice_V2",
"Dialog_OpenFile",
"Dialog_OpenFiles",
"Dialog_SaveFile",
"Dict_Clear",
"Dict_Create",
"Dict_Delete",
"Dict_GetItem",
"Dict_Items",
"Dict_Keys",
"Dict_SetItem",
"Dict_Update",
"Dict_Values",
"Element_ActivateWindowGround",
"Element_CheckBoxOperation",
"Element_CheckBoxOperation_v1",
"Element_CheckBoxOperation_v2",
"Element_CheckBoxOperation_v3",
"Element_Children",
"Element_ChildrenGround",
"Element_ChildrenV1",
"Element_Children_V1",
"Element_Children_V2",
"Element_Click",
"Element_ClickGround",
"Element_Click_V1",
"Element_Click_V2",
"Element_Click_V3",
"Element_Click_V4",
"Element_Click_V5",
"Element_Click_V6",
"Element_DesktopChildren",
"Element_ElementAarray",
"Element_ElementCaptureSimilar",
"Element_ElementExists",
"Element_Exists",
"Element_ExistsGround",
"Element_ExistsV1",
"Element_FileUploader",
"Element_GetAttribute",
"Element_GetAttributeGround",
"Element_GetAttribute_v1",
"Element_GetAttribute_v2",
"Element_GetAttribute_v3",
"Element_GetButtonEnable",
"Element_GetButtonEnableGround",
"Element_GetButtonEnable_v1",
"Element_GetButtonEnable_v2",
"Element_GetButtonEnable_v3",
"Element_GetButtonEnable_v4",
"Element_GetCheck",
"Element_GetCheckGround",
"Element_GetElement",
"Element_GetElementInfo",
"Element_GetElementInfo_V1",
"Element_GetElementNew",
"Element_GetElementV1",
"Element_GetElementV2",
"Element_GetHtml",
"Element_GetLineBarChartData",
"Element_GetPieChartData",
"Element_GetSelect",
"Element_GetSelectGround",
"Element_GetTableData",
"Element_GetText",
"Element_GetText_V1",
"Element_GetText_V2",
"Element_GetText_V3",
"Element_GetText_V4",
"Element_GetText_V5",
"Element_GetValue",
"Element_GetValueGround",
"Element_MouseTo",
"Element_MouseToGround",
"Element_MouseTo_V1",
"Element_MouseTo_V2",
"Element_MouseTo_V3",
"Element_MouseTo_V4",
"Element_MoveWindowGround",
"Element_Parent",
"Element_Parent_V1",
"Element_Parent_V2",
"Element_Region",
"Element_Region2",
"Element_Region2_v1",
"Element_Region2_v2",
"Element_Region2_v3",
"Element_RegionGround",
"Element_RestoreWindowGround",
"Element_ScrollIntoView",
"Element_ScrollIntoViewGround",
"Element_ScrollIntoView_v1",
"Element_ScrollIntoView_v2",
"Element_SelectOperation",
"Element_SelectOperation_v1",
"Element_SelectOperation_v2",
"Element_SelectOperation_v3",
"Element_SetAttribute",
"Element_SetAttributeGround",
"Element_SetAttribute_v1",
"Element_SetAttribute_v2",
"Element_SetCheck",
"Element_SetCheckGround",
"Element_SetSelect",
"Element_SetSelectGround",
"Element_SetValue",
"Element_SetValueGround",
"Element_SetValuePassword",
"Element_SetValuePassword_V1",
"Element_SetValuePassword_V5",
"Element_SetValuePassword_V6",
"Element_SetValue_V1",
"Element_SetValue_V2",
"Element_SetValue_V3",
"Element_SetValue_V4",
"Element_SetValue_V5",
"Element_SetValue_V6",
"Element_Shot",
"Element_ShotGround",
"Element_Shot_V1",
"Element_Shot_V2",
"Element_Sibling",
"Element_Sibling_V1",
"Element_Sibling_V2",
"Element_SimilarElementList",
"Element_SimilarElementList_V1",
"Element_SimilarElementList_V2",
"Element_StartAutoClosePopup",
"Element_StopAutoClosePopup",
"Element_WaitElement",
"Element_WaitElementGround",
"Element_WaitElement_v1",
"Element_WaitElement_v2",
"Element_WaitElement_v3",
"Element_WaitElement_v4",
"Element_WaitElement_v5",
"Element_exception_monitor_v2",
"Excel_ActiveSheet",
"Excel_ClearRange",
"Excel_Close",
"Excel_CopyRange",
"Excel_CopySheet",
"Excel_CreateSheet",
"Excel_Cs_Active",
"Excel_Cs_AutoFill",
"Excel_Cs_AutoFillV2",
"Excel_Cs_ClearExcelFilter",
"Excel_Cs_ClearRange",
"Excel_Cs_ClearRangeV2",
"Excel_Cs_ClearRangeV3",
"Excel_Cs_ClearRangeV4",
"Excel_Cs_Close",
"Excel_Cs_CloseV2",
"Excel_Cs_ColumnSplit",
"Excel_Cs_ColumnSplitV2",
"Excel_Cs_ConvertColumn",
"Excel_Cs_Copy",
"Excel_Cs_CopyRange",
"Excel_Cs_CopyRangeV2",
"Excel_Cs_CopyRangeV3",
"Excel_Cs_CopyV2",
"Excel_Cs_Delete",
"Excel_Cs_DeleteColumn",
"Excel_Cs_DeleteDuplicates",
"Excel_Cs_DeletePicture",
"Excel_Cs_DeletePictureV2",
"Excel_Cs_DeleteRange",
"Excel_Cs_DeleteRangeV2",
"Excel_Cs_DeleteRangeV3",
"Excel_Cs_DeleteRow",
"Excel_Cs_EnableExcelFilter",
"Excel_Cs_Encrypt",
"Excel_Cs_ExcelAddin",
"Excel_Cs_ExcelFilter",
"Excel_Cs_Export",
"Excel_Cs_Filter",
"Excel_Cs_FilterPivotTable",
"Excel_Cs_Find",
"Excel_Cs_FindV2",
"Excel_Cs_GetEditRange",
"Excel_Cs_GetEmptyCell",
"Excel_Cs_GetLastEmptyCell",
"Excel_Cs_GetName",
"Excel_Cs_GetPath",
"Excel_Cs_Group",
"Excel_Cs_Hide",
"Excel_Cs_Insert",
"Excel_Cs_InsertColumn",
"Excel_Cs_InsertColumnV2",
"Excel_Cs_InsertColumnV3",
"Excel_Cs_InsertPicture",
"Excel_Cs_InsertPictureV2",
"Excel_Cs_InsertPivotTable",
"Excel_Cs_InsertPivotView",
"Excel_Cs_InsertRow",
"Excel_Cs_InsertRowV2",
"Excel_Cs_InsertRowV3",
"Excel_Cs_Interop",
"Excel_Cs_Load",
"Excel_Cs_LoadV2",
"Excel_Cs_Merge",
"Excel_Cs_MergeCells",
"Excel_Cs_MergeCellsV2",
"Excel_Cs_Move",
"Excel_Cs_New",
"Excel_Cs_NewV2",
"Excel_Cs_NewV3",
"Excel_Cs_NewV4",
"Excel_Cs_NewV5",
"Excel_Cs_Open",
"Excel_Cs_OpenV2",
"Excel_Cs_OpenV3",
"Excel_Cs_OpenV4",
"Excel_Cs_PastRange",
"Excel_Cs_PastRangeV2",
"Excel_Cs_ReadCell",
"Excel_Cs_ReadCellBackground",
"Excel_Cs_ReadCellFormula",
"Excel_Cs_ReadColumn",
"Excel_Cs_ReadColumnCount",
"Excel_Cs_ReadContent",
"Excel_Cs_ReadContentV2",
"Excel_Cs_ReadContentV3",
"Excel_Cs_ReadContentV4",
"Excel_Cs_ReadRange",
"Excel_Cs_ReadRangeV2",
"Excel_Cs_ReadRow",
"Excel_Cs_ReadRowCount",
"Excel_Cs_RefreshAll",
"Excel_Cs_RefreshPivotTable",
"Excel_Cs_Rename",
"Excel_Cs_RunMacro",
"Excel_Cs_RunMacroV2",
"Excel_Cs_Save",
"Excel_Cs_SaveAs",
"Excel_Cs_Search",
"Excel_Cs_SelectRange",
"Excel_Cs_SelectRangeV2",
"Excel_Cs_SelectRangeV3",
"Excel_Cs_SetCellBackground",
"Excel_Cs_SetCellFont",
"Excel_Cs_SetCellFormat",
"Excel_Cs_SetCellFormat_V2",
"Excel_Cs_SetCellFormat_V3",
"Excel_Cs_SetHeight",
"Excel_Cs_SetHeightV1",
"Excel_Cs_SetRangeBackground",
"Excel_Cs_SetRangeBackgroundV2",
"Excel_Cs_SetRangeFont",
"Excel_Cs_SetRangeFontV2",
"Excel_Cs_SetSlicer",
"Excel_Cs_SetWidth",
"Excel_Cs_SetWidthV1",
"Excel_Cs_ShowTableStyle",
"Excel_Cs_Sort",
"Excel_Cs_SortV1",
"Excel_Cs_WriteCell",
"Excel_Cs_WriteCellV2",
"Excel_Cs_WriteColumn",
"Excel_Cs_WriteContent",
"Excel_Cs_WriteRange",
"Excel_Cs_WriteRangeV2",
"Excel_Cs_WriteRow",
"Excel_Cs_WriteRowV2",
"Excel_DeleteColumn",
"Excel_DeleteImage",
"Excel_DeleteRange",
"Excel_DeleteRow",
"Excel_DeleteSheet",
"Excel_ExecuteMacro",
"Excel_ExportRangeAsPicture",
"Excel_GetColData",
"Excel_GetColDataNew",
"Excel_GetColumnId",
"Excel_GetColumnsCount",
"Excel_GetPath",
"Excel_GetRowData",
"Excel_GetRowDataNew",
"Excel_GetRowsCount",
"Excel_GetSheetNames",
"Excel_GetSheetsName",
"Excel_InsertColumn",
"Excel_InsertImage",
"Excel_InsertRow",
"Excel_InsertSheet",
"Excel_Loop",
"Excel_New",
"Excel_NewExcel",
"Excel_Open",
"Excel_OpenExcel",
"Excel_OpenExcelNew",
"Excel_PasteRange",
"Excel_ReadCell",
"Excel_ReadCellNew",
"Excel_ReadRange",
"Excel_ReadRangeNew",
"Excel_RenameSheet",
"Excel_Save",
"Excel_SaveAs",
"Excel_SaveV2",
"Excel_SelectRange",
"Excel_SetCellColor",
"Excel_SetCellFontColor",
"Excel_SetColumnWidth",
"Excel_SetRangeColor",
"Excel_SetRangeFontColor",
"Excel_SetRowHeight",
"Excel_WriteCell",
"Excel_WriteCellNew",
"Excel_WriteColumn",
"Excel_WriteColumnNew",
"Excel_WriteRange",
"Excel_WriteRangeNew",
"Excel_WriteRow",
"Excel_WriteRowNew",
"ExceptionUtil_Throws",
"FTP_Connect",
"FTP_CreateDir",
"FTP_Cwd",
"FTP_Delete",
"FTP_Disconnect",
"FTP_Download",
"FTP_Exist",
"FTP_GetFileList",
"FTP_Rename",
"FTP_Upload",
"FileTypeConversion_Office2pdf",
"FileTypeConversion_Pdf2image2",
"File_CompressFile",
"File_Copy",
"File_Copy_V1",
"File_CreateFile",
"File_CreateFolder",
"File_DecompressFile",
"File_Delete",
"File_DeleteFile",
"File_EmptyFolder",
"File_FileExists",
"File_File_Move",
"File_GetFileInfo",
"File_GetFileList",
"File_GetFileList_V1",
"File_GetFolderList",
"File_GetFolderList_V1",
"File_MakeDir",
"File_MakeFolder",
"File_Move",
"File_MoveFolder",
"File_OpenFile",
"File_PathExists",
"File_PathSize",
"File_PathSizeNew",
"File_Read",
"File_ReadXml",
"File_Rename",
"File_Rename_V1",
"File_WaitFile",
"File_Write",
"File_Write_V1",
"GoogleTable_ChangeSheet",
"GoogleTable_CopyPasteSheet",
"GoogleTable_DownloadSheets",
"GoogleTable_GetAllData",
"GoogleTable_GetAllSheetsName",
"GoogleTable_GetColumnsByTableTitle",
"GoogleTable_GetSheetRowCount",
"GoogleTable_RenameSheet",
"GoogleTable_WriteToSheetCell",
"GoogleTable_WriteToSheetCellFormula",
"GoogleTable_WriteToSheetRegionColumns",
"GoogleTable_WriteToSheetRegionRows",
"GoogleTable_WriteToSheetRegionregion",
"Http_Get",
"Http_Get_V1",
"Http_Get_V2",
"Http_Http_Request",
"Http_Post",
"Http_Post_V2",
"Http_Post_V3",
"Image_Base64Decode",
"Image_Base64Encode",
"Image_Click",
"Image_Click_V1",
"Image_Click_V2",
"Image_Click_V3",
"Image_CropImg",
"Image_Exists",
"Image_Exists_V1",
"Image_Find",
"Image_Find_V1",
"Image_Location",
"Image_Location_V1",
"Image_Move",
"Image_Move_V1",
"Image_Move_V2",
"Image_RelativePosition",
"Image_Screenshot",
"Image_Wait",
"Image_Wait_V1",
"Ini_DeleteKey",
"Ini_DeleteSection",
"Ini_ListKey",
"Ini_ListSection",
"Ini_Read",
"Ini_Write",
"JSON_Parse",
"JSON_Stringify",
"Keyboard_DisableManualOperation",
"Keyboard_DriveSend",
"Keyboard_DriveSend_V1",
"Keyboard_DriveSend_V2",
"Keyboard_EnableManualOperation",
"Keyboard_Press",
"Keyboard_PressNew",
"Keyboard_Send",
"Keyboard_Send_V1",
"List_ClearList",
"List_CreateList",
"List_DeleteList",
"List_GetIndex",
"List_GetListItem",
"List_InsertList",
"List_ListDuplication",
"List_ListIntersection",
"List_ListLength",
"List_ListMerge",
"List_ListSorted",
"List_SetListItem",
"Log_Error",
"Log_Info",
"Mail_DoGetMailMessage",
"Mail_DoGetMailMessage_v1",
"Mail_DoGetMailMessage_v2",
"Mail_DoMoveMail",
"Mail_DoMoveMail_v1",
"Mail_DoReplyMail",
"Mail_DoReplyMail_v1",
"Mail_DoSendMail",
"Mail_DoSendMail_v1",
"Mail_ExConnect",
"Mail_ExOperateMail",
"Mail_ExSearchMail",
"Mail_ExSendMail",
"Mail_FindMail",
"Mail_FindMail_v1",
"Mail_FindMail_v2",
"Mail_MarkSeen",
"Mail_OperateMail",
"Mail_RecvClose",
"Mail_RecvConnect",
"Mail_RecvCount",
"Mail_RecvGetList",
"Mail_RecvMailGet",
"Mail_ReplyMail",
"Mail_ReplyMail_v1",
"Mail_ReplyMail_v2",
"Mail_Send",
"Mail_Send_V1",
"Mail_UnionConnect",
"Mail_UnionSend",
"Mail_UnionSend_v1",
"Mail_UnmarkSeen",
"Math_Abs",
"Math_Cos",
"Math_Exp",
"Math_Hex",
"Math_Int",
"Math_Oct",
"Math_Pow",
"Math_Round",
"Math_Scale",
"Math_Sgn",
"Math_Sin",
"Math_Sqrt",
"Math_Tan",
"MessageNotification_DingTalk_Message",
"MessageNotification_Feishu_Message",
"MessageNotification_WXWork_Message",
"Mouse_Click",
"Mouse_ClickCombine",
"Mouse_ClickCombine_v1",
"Mouse_ClickCombine_v2",
"Mouse_ClickCombine_v3",
"Mouse_ClickCombine_v4",
"Mouse_ClickNew",
"Mouse_Drag",
"Mouse_DragTo",
"Mouse_DragToNew",
"Mouse_DragToV1",
"Mouse_DragToV2",
"Mouse_Move",
"Mouse_MoveTo",
"Mouse_MoveToV1",
"Mouse_MoveToV2",
"Mouse_RollTo",
"Mouse_Scroll",
"NLP_AnalyseProductReview",
"NLP_BatchAnalyseProductReview",
"NLP_EmotionalAnalysis",
"NLP_KeyWordsAnalysis",
"NLP_PerspectiveAnalysis",
"NLP_SemanticSimilarity",
"NLP_SplitText",
"NLP_SplitWords",
"NLP_XunFei_FeelingAnalysis",
"NLP_XunFei_KeywordExtraction",
"NLP_XunFei_MachineTranslation",
"NLP_XunFei_NLPBaseServer",
"OCR_AccountPageV2",
"OCR_AmountIdentification",
"OCR_BankCardV2",
"OCR_BankCardV3",
"OCR_BusinessCardV2",
"OCR_BusinessLicenseV2",
"OCR_BusinessLicenseV3",
"OCR_CalculationCode",
"OCR_CommonEnglishNumbersCode",
"OCR_DriverLicenseV2",
"OCR_DrivingLicenseV2",
"OCR_GeneralTextV2",
"OCR_HouseCertV2",
"OCR_IdCardV2",
"OCR_IdCardV3",
"OCR_KeyValueIdentification",
"OCR_MergeCarOCR",
"OCR_MergeCardOCR",
"OCR_MergeEducationOCR",
"OCR_MergeGeneralOCR",
"OCR_MergeOtherOCR",
"OCR_MergePaperOCR",
"OCR_OfficialSealV2",
"OCR_PassportV2",
"OCR_PlateLicenseV2",
"OCR_RealEstateCertV2",
"OCR_TaxiInvoiceV2",
"OCR_TrainTicketV2",
"OCR_VatInvoiceV2",
"OCR_VatInvoiceV3",
"OCR_VehicleInvoiceV2",
"OCR_VinV2",
"OcrOffline_GetOcrTable",
"OcrOffline_GetOcrTextNew",
"OcrOffline_GetOcrTextPosition",
"PDF_ConcatPdf",
"PDF_ConcatPdfV1",
"PDF_CreateNewPdf",
"PDF_GetPageCount",
"PDF_GetPdfImg",
"PDF_GetPdfInformation",
"PDF_GetPdfPageNum",
"PDF_GetPdfTable",
"PDF_GetPdfText",
"PDF_PdfEncryption",
"PDF_PdfToImg",
"PDF_SetPdfWaterMark",
"PDF_SetPdfWaterMarkV1",
"Regex_Find",
"Regex_FindAll",
"Regex_FindAllNew",
"Regex_FindNew",
"Regex_FindNew_1",
"Regex_FindStr",
"Regex_FindStrV1",
"Regex_Test",
"Regex_TestNew",
"Scenario_TextComparison",
"ScreenControl_ScreenUnlock",
"ScreenControl_Screenlock",
"StrUtil_AddToStr",
"StrUtil_CaseChange",
"StrUtil_CharAsc",
"StrUtil_CharCode",
"StrUtil_CompleteStr",
"StrUtil_CreateRandomStr",
"StrUtil_CutOutStr",
"StrUtil_CutOutStrV1",
"StrUtil_DelTrim",
"StrUtil_InStr",
"StrUtil_Left",
"StrUtil_Len",
"StrUtil_ListToString",
"StrUtil_LookUpStr",
"StrUtil_LowerCase",
"StrUtil_Ltrim",
"StrUtil_Mid",
"StrUtil_Replace",
"StrUtil_ReverseStr",
"StrUtil_Right",
"StrUtil_Rtrim",
"StrUtil_Split",
"StrUtil_SplitStr",
"StrUtil_Trim",
"StrUtil_UpperCase",
"System_AddCredential",
"System_CloseRemoteDesktop",
"System_ConnectRemoteDesktop",
"System_DeleteCredential",
"System_ExecuteCommand",
"System_ExecuteCommandV1",
"System_GetEnv",
"System_GetHomePath",
"System_GetInputMethodState",
"System_GetSystemPath",
"System_GetTempPath",
"System_PlaySound",
"System_ReadCredential",
"System_ScreenSaverShow",
"System_ScreenSaverShowV1",
"System_ScreenSaverStop",
"System_SetEnv",
"System_SetInputMethodState",
"Time_CalDate",
"Time_Date",
"Time_DateOffset",
"Time_DateOffset_V1",
"Time_DateToTimestamp",
"Time_DatetimeToTimestamp",
"Time_Day",
"Time_Format",
"Time_FormatNew",
"Time_GetDate",
"Time_GetDateV1",
"Time_GetDateV2",
"Time_GetDatetimeObj",
"Time_Hour",
"Time_Minute",
"Time_Month",
"Time_Now",
"Time_Second",
"Time_Time",
"Time_TimeStamp",
"Time_TimeTypeConversion",
"Time_TimeTypeConversion_V1",
"Time_WeekDay",
"Time_Year",
"Trigger.FileArrival",
"Trigger.Manual",
"Trigger.Schedule",
"WebBrowser_BatchDataCrawl",
"WebBrowser_BatchDataCrawlNew",
"WebBrowser_BatchDataCrawlNewV1",
"WebBrowser_Close",
"WebBrowser_CloseWeb",
"WebBrowser_CloseWeb_V1",
"WebBrowser_CloseWeb_V2",
"WebBrowser_Close_V1",
"WebBrowser_Create",
"WebBrowser_CreateBackground",
"WebBrowser_CreateV2",
"WebBrowser_CreateV3",
"WebBrowser_DataCollection",
"WebBrowser_DataCollectionV1",
"WebBrowser_DataCollectionV2",
"WebBrowser_DataCollectionV3",
"WebBrowser_DataCollectionV4",
"WebBrowser_DataCollectionV5",
"WebBrowser_DataCrawl",
"WebBrowser_DataCrawl_software",
"WebBrowser_DataCrawl_web",
"WebBrowser_DataCrawler",
"WebBrowser_DownFile",
"WebBrowser_DownFile_V1",
"WebBrowser_DownloadFile",
"WebBrowser_DownloadFile_V1",
"WebBrowser_GetBrowserPic",
"WebBrowser_GetBrowserPicV1",
"WebBrowser_GetCookie",
"WebBrowser_GetCookieNew",
"WebBrowser_GetCookies",
"WebBrowser_GetDocument",
"WebBrowser_GetScrollPos",
"WebBrowser_GetScrollPos_V1",
"WebBrowser_GetTAB",
"WebBrowser_GetTAB_V1",
"WebBrowser_GetTAB_V2",
"WebBrowser_GetTitle",
"WebBrowser_GetUrl",
"WebBrowser_GetWeblistening",
"WebBrowser_GoBack",
"WebBrowser_GoForward",
"WebBrowser_GoUrl",
"WebBrowser_Maximize",
"WebBrowser_Minimize",
"WebBrowser_Navigate",
"WebBrowser_Reload",
"WebBrowser_RunJs",
"WebBrowser_RunJsInIeBySelector",
"WebBrowser_RunJsInIeBySelectorGround",
"WebBrowser_RunJsInIeBySelector_v1",
"WebBrowser_RunJsInIeBySelector_v2",
"WebBrowser_RunJsInIeBySelector_v3",
"WebBrowser_RunJsInIeByTitle",
"WebBrowser_SaveAs",
"WebBrowser_SaveAs_V1",
"WebBrowser_Screenshot",
"WebBrowser_SetCookies",
"WebBrowser_SetCookies_V1",
"WebBrowser_SetScrollPos",
"WebBrowser_SetScrollPos_V1",
"WebBrowser_StartWeblistening",
"WebBrowser_Stop",
"WebBrowser_StopWeblistening",
"WebBrowser_Switch",
"WebBrowser_Switch_V1",
"WebBrowser_Upload",
"WebBrowser_UploadDialog",
"WebBrowser_Wait",
"Window_Activate",
"Window_ActiveWindow",
"Window_ActiveWindow_v1",
"Window_Close",
"Window_CloseWindow",
"Window_CloseWindow_v1",
"Window_Exists",
"Window_Get",
"Window_GetActive",
"Window_GetActiveWindow",
"Window_GetRect",
"Window_GetScreenSize",
"Window_GetWindow",
"Window_GetWindowMessage",
"Window_GetWindowMessage_v1",
"Window_GetWindowRect",
"Window_GetWindow_v1",
"Window_MaximumSize",
"Window_MoveWindow",
"Window_MoveWindow_v1",
"Window_SetActive",
"Window_SetPos",
"Window_SetWindowShow",
"Window_SetWindowState",
"Window_SetWindowState_v1",
"Window_SizeWindow",
"Window_SizeWindow_v1",
"Window_WaitWindow",
"Window_WindowExists",
"Window_WindowList",
"Word_Close",
"Word_CopySelect",
"Word_CutSelect",
"Word_DeleteSelect",
"Word_Enter",
"Word_GetPath",
"Word_InsertPage",
"Word_InsertPicture",
"Word_MovePosition",
"Word_New",
"Word_New_V1",
"Word_Open",
"Word_PasteSelect",
"Word_PositionToSelect",
"Word_ReadAll",
"Word_ReadSelect",
"Word_ReadTable",
"Word_Replace",
"Word_Save",
"Word_SaveAs",
"Word_SelectAll",
"Word_SelectRow",
"Word_SetAlign",
"Word_SetFontColor",
"Word_SetFontName",
"Word_SetFontSize",
"Word_SetFontStyle",
"Word_SetPosition",
"Word_Write",
"Word_WriteTable",
"child_modules_v1",
"concurrent_child_process_v1",
"logic_control_break_for",
"logic_control_if_ai_vision",
"logic_control_next_for",
"logic_control_stop",
"logic_control_stop_return",
"logic_control_var"
]
}

View File

@ -0,0 +1,36 @@
/**
* 能力注册快照(任务 0.3,见 docs/rpa-core-refactor-tasks.md)
*
* 以与生产完全相同的路径(import "../src/main/capabilities" 的副作用注册)
* 拉起全部能力模块,把运行时注册表的 id 清单写入
* resources/capability-snapshot.json。
*
* 用法:npm run snapshot
* 抽离改造各阶段完成后重跑并 git diff,快照变化必须为零(行为回归基准)。
*/
import { writeFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { describe, expect, it } from "vitest";
import { capabilityCount, capabilityIds } from "../src/main/capabilities";
const OUT_FILE = path.join(
path.dirname(fileURLToPath(import.meta.url)),
"..",
"resources",
"capability-snapshot.json"
);
describe("能力注册快照", () => {
it("全量注册后导出能力 id 清单", () => {
const ids = [...capabilityIds()].sort();
expect(ids.length).toBeGreaterThan(0);
const snapshot = {
generatedAt: new Date().toISOString(),
count: ids.length,
ids
};
writeFileSync(OUT_FILE, JSON.stringify(snapshot, null, 2) + "\n", "utf8");
console.log(`[能力快照] ${capabilityCount()} 个能力已写入 ${path.basename(OUT_FILE)}`);
});
});

View File

@ -1,9 +1,8 @@
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { readFileSync } from "node:fs";
import { afterAll, describe, expect, it } from "vitest";
import { getHandler } from "../engine/registry";
import { capabilityIds, getHandler } from "../engine/registry";
import { RuntimeError } from "../engine/types";
import type { CatalogComponent, FlowNode } from "../../shared/types";
import type { RunContext } from "../engine/types";
@ -195,10 +194,10 @@ describe("数据处理/文件/编排 冒烟", () => {
expect(await run("File_FileExists", { path: copy })).toBe(false);
const renamed = await run("File_Rename", { pathSrc: moved, name: "renamed.txt" });
expect(String(renamed)).toContain("renamed.txt");
const zip = await run("File_CompressFile", { pathSrc: created, pathDest: path.join(sandbox, "pack.zip") });
const zip = await run("File_CompressFile", { pathSrc: created, pathDest: path.join(sandbox, "pack.zip"), direct_type: "0" });
expect(String(zip)).toContain("pack.zip");
const unzipDir = path.join(sandbox, "unpacked");
await run("File_DecompressFile", { path: path.join(sandbox, "pack.zip"), target: unzipDir });
await run("File_DecompressFile", { path: path.join(sandbox, "pack.zip"), target: unzipDir, direct_type: "0" });
expect(await run("File_FileExists", { path: path.join(unzipDir, "a.txt") })).toBe(true);
expect(await run("File_WaitFile", { file_path: created, time_out: 1 })).toBe(true);
await expect(run("File_WaitFile", { file_path: path.join(dir, "ghost.txt"), time_out: 1 })).rejects.toThrow(/超时/);
@ -252,9 +251,7 @@ describe("数据处理/文件/编排 冒烟", () => {
});
it("全量健康检查: 已注册组件空参调用不产生非结构化崩溃", async () => {
const ids: string[] = JSON.parse(
readFileSync("D:/wordkb/2026-10-28-10-36-47/PRA-only-demo/live-ids.json", "utf8")
) as string[];
const ids: string[] = capabilityIds();
const skip = new Set([
"FTP_Connect", "FTP_Upload", "FTP_Download", "FTP_Delete", "FTP_Rename", "FTP_Cwd", "FTP_GetFileList", "FTP_CreateDir", "FTP_Exist", "FTP_Disconnect",
"Database_DBConnect", "Database_SQLExecute", "Database_SingleSQLQuery", "Database_AllSQLQuery_V1", "Database_BatchSQLExecute", "Database_BatchInsertExecute", "Database_CloseDBConnect",

View File

@ -64,14 +64,29 @@ describe("键盘输入组件真实冒烟", () => {
const { promisify } = await import("node:util");
const runPs = promisify(execFile);
const ps = (cmd: string) => runPs("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", cmd], { windowsHide: true, timeout: 30000 });
// Win11 记事本窗口标题是「无标题 - Notepad」; 沙盒内 Start-Process notepad 别名解析失败, 用完整路径
await ps("Start-Process $env:SystemRoot\\System32\\notepad.exe; $diag=''; $ok=$false; foreach($i in 1..24){ $procs=Get-Process Notepad -ErrorAction SilentlyContinue; if($procs){ $diag=\"procs:$($procs.Count) titles:$(($procs|ForEach-Object{$_.MainWindowTitle}) -join '|')\"; $p=Get-Process | Where-Object {$_.MainWindowTitle -like '*Notepad*'}; if($p){$ok=$true; break} } else { $diag='no-process' }; Start-Sleep -Milliseconds 500 }; if(-not $ok){ throw \"notepad not visible: $diag\" }");
// 窗口标题随系统语言变化(英文 Notepad / 中文 记事本), 不硬编码, 启动后动态取实际标题
await ps("Start-Process $env:SystemRoot\\System32\\notepad.exe; $diag=''; $ok=$false; foreach($i in 1..24){ $procs=Get-Process Notepad -ErrorAction SilentlyContinue; if($procs){ $p=$procs | Where-Object {$_.MainWindowTitle}; if($p){$ok=$true; break} } else { $diag='no-process' }; Start-Sleep -Milliseconds 500 }; if(-not $ok){ throw \"notepad not visible: $diag\" }");
try {
await invoke("Keyboard_Send_V1", { words: "目标窗口输入'测试", interval: "5", fuctype: "1", window_title: "Notepad" });
const titlePs = "[Console]::OutputEncoding=[System.Text.UTF8Encoding]::new($false); (Get-Process Notepad | Where-Object { $_.MainWindowTitle } | Select-Object -First 1).MainWindowTitle";
const title = (await ps(titlePs)).stdout.trim();
expect(title.length).toBeGreaterThan(0);
// GUI 焦点抢占受系统前台锁约束, 偶发失败属正常抖动, 有界重试
let lastErr: unknown;
for (let attempt = 1; attempt <= 3; attempt += 1) {
try {
await invoke("Keyboard_Send_V1", { words: "目标窗口输入'测试", interval: "5", fuctype: "1", window_title: title });
lastErr = undefined;
break;
} catch (error) {
lastErr = error;
await new Promise((r) => setTimeout(r, 1000));
}
}
if (lastErr) throw lastErr;
await new Promise((r) => setTimeout(r, 300));
// activateWindowScript 内部已校验前台句柄=目标窗口, 这里再确认记事本进程窗口标题匹配
const fg = await ps("[Console]::OutputEncoding=[System.Text.UTF8Encoding]::new($false); (Get-Process Notepad | Where-Object { $_.MainWindowTitle } | Select-Object -First 1).MainWindowTitle");
expect(fg.stdout).toContain("Notepad");
// activateWindowScript 内部已校验前台句柄=目标窗口, 这里再确认前台标题仍是记事本(输入后标题会带 * 脏标记前缀)
const fg = await ps(titlePs);
expect(fg.stdout.trim()).toContain(title);
console.log("[键盘输入] 目标窗口激活 ✓ 前台:", fg.stdout.trim());
} finally {
await ps("Get-Process notepad* -ErrorAction SilentlyContinue | Stop-Process -Force").catch(() => {});

View File

@ -30,6 +30,17 @@ async function cursorPos(): Promise<[number, number]> {
return stdout.trim().split(",").map(Number) as [number, number];
}
/** 共享桌面环境下光标可能被其他进程短暂挪动,轮询等待落位(容差 px),超时返回最后一次读数 */
async function waitForCursor(target: [number, number], tolerance = 0, attempts = 10, gapMs = 100): Promise<[number, number]> {
let pos = await cursorPos();
for (let i = 0; i < attempts; i += 1) {
if (Math.abs(pos[0] - target[0]) <= tolerance && Math.abs(pos[1] - target[1]) <= tolerance) return pos;
await new Promise((r) => setTimeout(r, gapMs));
pos = await cursorPos();
}
return pos;
}
async function invoke(componentId: string, args: Record<string, unknown>): Promise<unknown> {
const handler = getHandler(componentId);
expect(handler).toBeTypeOf("function");
@ -47,8 +58,7 @@ describe("移动鼠标组件真实冒烟", () => {
// 用户屏幕框选生成的浮点对象坐标(此前直接报「鼠标坐标无效」)
const out = await invoke("Mouse_MoveToV2", { location: { x: 1397, y: 227.60000610351562 }, position: "0", move_type: "2", speed: 100 }) as { x: number; y: number };
expect(out).toEqual({ x: 1397, y: 228 });
await new Promise((r) => setTimeout(r, 150));
const pos = await cursorPos();
const pos = await waitForCursor([1397, 228]);
expect(pos[0]).toBe(1397);
expect(pos[1]).toBe(228);
console.log("[移动鼠标] 对象坐标解析 + 瞬间移动落位 ✓ 实际光标:", pos);
@ -58,8 +68,7 @@ describe("移动鼠标组件真实冒烟", () => {
original = await cursorPos();
const out = await invoke("Mouse_MoveToV2", { location: "[300,300]", position: "0", move_type: "0", speed: 60 }) as { x: number; y: number };
expect(out).toEqual({ x: 300, y: 300 });
await new Promise((r) => setTimeout(r, 200));
const pos = await cursorPos();
const pos = await waitForCursor([300, 300], 2);
expect(Math.abs(pos[0] - 300)).toBeLessThanOrEqual(2);
expect(Math.abs(pos[1] - 300)).toBeLessThanOrEqual(2);
console.log("[移动鼠标] 模拟人工移动 ✓ 实际光标:", pos);
@ -69,7 +78,7 @@ describe("移动鼠标组件真实冒烟", () => {
original = await cursorPos();
const out = await invoke("Mouse_MoveToV2", { location: "[500,400]", position: "0", move_type: "1", speed: 80 }) as { x: number; y: number };
expect(out).toEqual({ x: 500, y: 400 });
const pos = await cursorPos();
const pos = await waitForCursor([500, 400]);
expect(pos[0]).toBe(500);
expect(pos[1]).toBe(400);
console.log("[移动鼠标] 匀速直线 + 字符串坐标 ✓ 实际光标:", pos);

View File

@ -121,21 +121,30 @@ describe("网络与消息组件冒烟", () => {
it("Http_Http_Request: PUT方法+Cookie+保存响应", async () => {
const { server, port, requests } = await startHttpServer();
const saveTo = "D:/office-test2/http-smoke-response.json";
await run("Http_Http_Request", {
url: `http://127.0.0.1:${port}/update`,
method: "PUT",
body: "raw-payload",
cookies: JSON.stringify({ session: "s-77", lang: "zh" }),
file_path: saveTo
});
server.close();
expect(requests[0].method).toBe("PUT");
expect(requests[0].headers.cookie).toBe("session=s-77; lang=zh");
const { readFileSync } = await import("node:fs");
const saved = JSON.parse(readFileSync(saveTo, "utf8")) as { echo: string };
expect(saved.echo).toBe("raw-payload");
console.log("[Http_Http_Request] 通过: PUT+Cookie+响应落盘均正确");
// 保存路径用系统临时目录,不硬编码盘符路径(可移植 + 沙盒可写)
const { tmpdir } = await import("node:os");
const { join } = await import("node:path");
const { mkdtempSync, rmSync } = await import("node:fs");
const saveDir = mkdtempSync(join(tmpdir(), "rpa-http-smoke-"));
const saveTo = join(saveDir, "http-smoke-response.json");
try {
await run("Http_Http_Request", {
url: `http://127.0.0.1:${port}/update`,
method: "PUT",
body: "raw-payload",
cookies: JSON.stringify({ session: "s-77", lang: "zh" }),
file_path: saveTo
});
server.close();
expect(requests[0].method).toBe("PUT");
expect(requests[0].headers.cookie).toBe("session=s-77; lang=zh");
const { readFileSync } = await import("node:fs");
const saved = JSON.parse(readFileSync(saveTo, "utf8")) as { echo: string };
expect(saved.echo).toBe("raw-payload");
console.log("[Http_Http_Request] 通过: PUT+Cookie+响应落盘均正确");
} finally {
rmSync(saveDir, { recursive: true, force: true });
}
});
it("Http 错误路径: 5xx 明确报错 + 超时报错", async () => {

View File

@ -1,5 +1,6 @@
import { createServer, type Server } from "node:http";
import { promises as fs } from "node:fs";
import { mkdtempSync, promises as fs, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../../shared/types";
@ -44,7 +45,8 @@ const PAGE_DISABLED = `<button id="disabledBtn" disabled>不可用</button>`;
let server: Server;
let baseUrl = "";
const outDir = "D:/office-test2/web-test";
// 输出目录用系统临时目录,不硬编码盘符路径(可移植 + 沙盒可写)
const outDir = mkdtempSync(path.join(tmpdir(), "rpa-web-smoke-"));
const uploadFile = path.join(outDir, "upload-src.txt");
let browser: BrowserLike;
let ctx: RunContext;
@ -93,7 +95,8 @@ beforeAll(async () => {
afterAll(async () => {
try { await browser?.close(); } catch { /* 进程退出兜底 */ }
await new Promise<void>((resolve) => server.close(() => resolve()));
await new Promise<void>((resolve) => { server.close(() => resolve()); });
rmSync(outDir, { recursive: true, force: true });
});
describe("网页自动化真实冒烟(Chrome 无头 + CDP)", () => {

9
vitest.config.ts Normal file
View File

@ -0,0 +1,9 @@
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
// 桌面自动化冒烟测试(键盘/鼠标/窗口焦点/剪贴板)共用同一物理桌面,
// 并发执行会互相抢占焦点导致偶发失败,因此测试文件一律串行执行。
fileParallelism: false
}
});