阶段0-基线与护栏: 修复不可移植/抖动测试全绿(341过), vitest串行执行防桌面竞争, 新增运行时能力注册快照(909个id)
This commit is contained in:
parent
f35f0ac979
commit
4139400dbd
@ -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"
|
||||
|
||||
915
resources/capability-snapshot.json
Normal file
915
resources/capability-snapshot.json
Normal 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"
|
||||
]
|
||||
}
|
||||
36
scripts/capability-snapshot.test.ts
Normal file
36
scripts/capability-snapshot.test.ts
Normal 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)}`);
|
||||
});
|
||||
});
|
||||
@ -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",
|
||||
|
||||
@ -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(() => {});
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 () => {
|
||||
|
||||
@ -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
9
vitest.config.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
// 桌面自动化冒烟测试(键盘/鼠标/窗口焦点/剪贴板)共用同一物理桌面,
|
||||
// 并发执行会互相抢占焦点导致偶发失败,因此测试文件一律串行执行。
|
||||
fileParallelism: false
|
||||
}
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user