diff --git a/README.md b/README.md index aa40562..3377d7e 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,14 @@ PyBreeze is not just a code editor — it is a command center for the automation - Password and private key authentication - Interactive command execution - Remote file tree viewer with CRUD operations (create folder, rename, delete, upload, download) + - Interactive TOFU host-key verification with confirmed keys persisted to `~/.pybreeze/ssh_known_hosts` +- **Diagram Editor** — Built-in WYSIWYG architecture-diagram editor: + - Rectangle, rounded rectangle, ellipse, diamond nodes, connection lines, and free text + - Image insertion from local files or URLs (URL fetches are SSRF-validated and size-capped) + - Mermaid `flowchart` / `graph` import + - Save/Open as `.diagram.json`, export to PNG or SVG + - Undo/redo, align, distribute, grid, snap, and zoom controls +- **File Tree Context Menu** — Right-click any file or folder in the project tree to create files/folders, rename, delete, copy absolute or relative paths, or reveal the item in your platform file manager. Renaming or deleting a file that is currently open in an editor tab keeps the tab in sync. - **Package Manager** — Install automation modules and build tools directly from the IDE menu without leaving the editor. - **Integrated Documentation** — Quick access to documentation and GitHub pages for each automation module directly from the menu bar. @@ -82,6 +90,7 @@ PyBreeze is not just a code editor — it is a command center for the automation - Step-by-step analysis - Summary generation - **Skill Prompt Editor** — Define and manage reusable skill-based prompts (code explanation, code review templates) that can be sent to LLM APIs. +- **Skill Send GUI** — Pick a skill prompt template, optionally edit the prompt text, send it to an LLM API endpoint, and view the response — all in a dedicated tab or dock. ### Plugin System @@ -108,7 +117,70 @@ The IDE interface supports multiple languages: ## Architecture -![Architecture Diagram](architecture_diagram/AutomationEditorArchitectureDiagram.drawio.png) +```mermaid +flowchart TB + UI["PyBreeze UI · PySide6"] + + subgraph Editor["JEditor (Base Editor)"] + direction LR + E1["Code Editor + Tabs"] + E2["File Tree"] + E3["Syntax Highlighting"] + E4["Plugin System"] + end + + subgraph Automation["Automation Menu"] + direction LR + A1["APITestka"] + A2["AutoControl"] + A3["WebRunner"] + A4["LoadDensity"] + A5["FileAutomation"] + A6["MailThunder"] + A7["TestPioneer"] + end + + subgraph Executors["Subprocess Executors · TaskProcessManager"] + direction LR + X1["je_api_testka"] + X2["je_auto_control"] + X3["je_web_runner"] + X4["je_load_density"] + X5["automation-file"] + X6["je-mail-thunder"] + X7["test_pioneer"] + end + + subgraph Tools["Tools"] + direction LR + T1["SSH · paramiko"] + T2["AI Code Review"] + T3["CoT Prompt Editor"] + T4["Skill Prompt Editor"] + T5["Skill Send GUI"] + T6["Diagram Editor"] + T7["JupyterLab"] + end + + subgraph Install["Install Menu"] + direction LR + I1["Module Installers"] + I2["Build Tools"] + end + + UI --> Editor + UI --> Automation + UI --> Tools + UI --> Install + + A1 --> X1 + A2 --> X2 + A3 --> X3 + A4 --> X4 + A5 --> X5 + A6 --> X6 + A7 --> X7 +``` PyBreeze follows a modular architecture: @@ -132,6 +204,8 @@ PyBreeze UI (PySide6) │ ├── AI Code Review Client │ ├── CoT Prompt Editor │ ├── Skill Prompt Editor +│ ├── Skill Send GUI +│ ├── Diagram Editor (WYSIWYG, Mermaid import, PNG/SVG export) │ └── JupyterLab Integration └── Install Menu ├── Automation Module Installers @@ -273,8 +347,9 @@ PyBreeze/ │ │ └── process_executor/python_task_process_manager.py │ ├── extend_multi_language/ # Built-in translations (English, Traditional Chinese) │ ├── pybreeze_ui/ -│ │ ├── editor_main/ # Main window (extends JEditor) -│ │ ├── connect_gui/ssh/ # SSH client widgets +│ │ ├── editor_main/ # Main window (extends JEditor) + file tree context menu +│ │ ├── connect_gui/ssh/ # SSH client widgets (TOFU host-key verification) +│ │ ├── diagram_editor/ # WYSIWYG architecture-diagram editor │ │ ├── extend_ai_gui/ # AI code review & prompt editors │ │ ├── jupyter_lab_gui/ # JupyterLab integration │ │ ├── menu/ # Menu bar construction diff --git a/README/README_zh-CN.md b/README/README_zh-CN.md index 022a4d5..d40fc53 100644 --- a/README/README_zh-CN.md +++ b/README/README_zh-CN.md @@ -68,6 +68,14 @@ PyBreeze 不仅仅是一个代码编辑器——它是自动化生命周期的 - 密码与私钥认证 - 交互式命令执行 - 远程文件树查看器,支持 CRUD 操作(创建文件夹、重命名、删除、上传、下载) + - 交互式 TOFU host key 验证,已确认的密钥会持久化到 `~/.pybreeze/ssh_known_hosts` +- **架构图编辑器** — 内置的 WYSIWYG 架构图编辑器: + - 矩形、圆角矩形、椭圆、菱形节点、连线、自由文本 + - 从本地文件或 URL 插入图片(URL 下载会做 SSRF 验证并有大小上限) + - 支持 Mermaid `flowchart` / `graph` 导入 + - 保存/打开为 `.diagram.json`,导出为 PNG 或 SVG + - Undo/redo、对齐、分布、Grid、Snap、Zoom 控制 +- **文件树右键菜单** — 在项目文件树中对任何文件或文件夹右键,可创建文件/文件夹、重命名、删除、复制绝对或相对路径、在系统文件管理器中打开。重命名或删除当前已在编辑器标签页中打开的文件时,标签页会同步更新。 - **包管理器** — 直接从 IDE 菜单安装自动化模块和构建工具,无需离开编辑器。 - **集成文档** — 从菜单栏快速访问每个自动化模块的文档和 GitHub 页面。 @@ -81,6 +89,7 @@ PyBreeze 不仅仅是一个代码编辑器——它是自动化生命周期的 - 逐步分析 - 摘要生成 - **Skill 提示词编辑器** — 定义和管理可重复使用的技能型提示词(代码解说、代码审查模板),可发送至 LLM API。 +- **Skill Send GUI** — 在独立的标签页或停靠面板中选择技能提示词模板、按需编辑提示词内容、发送到 LLM API 端点并查看响应。 ### 插件系统 @@ -107,7 +116,70 @@ IDE 界面支持多种语言: ## 架构设计 -![架构图](../architecture_diagram/AutomationEditorArchitectureDiagram.drawio.png) +```mermaid +flowchart TB + UI["PyBreeze UI · PySide6"] + + subgraph Editor["JEditor 基础编辑器"] + direction LR + E1["代码编辑器 + 标签页"] + E2["文件树"] + E3["语法高亮"] + E4["插件系统"] + end + + subgraph Automation["自动化菜单"] + direction LR + A1["APITestka"] + A2["AutoControl"] + A3["WebRunner"] + A4["LoadDensity"] + A5["FileAutomation"] + A6["MailThunder"] + A7["TestPioneer"] + end + + subgraph Executors["子进程执行器 · TaskProcessManager"] + direction LR + X1["je_api_testka"] + X2["je_auto_control"] + X3["je_web_runner"] + X4["je_load_density"] + X5["automation-file"] + X6["je-mail-thunder"] + X7["test_pioneer"] + end + + subgraph Tools["工具"] + direction LR + T1["SSH · paramiko"] + T2["AI 代码审查"] + T3["CoT 提示词编辑器"] + T4["Skill 提示词编辑器"] + T5["Skill Send GUI"] + T6["架构图编辑器"] + T7["JupyterLab"] + end + + subgraph Install["安装菜单"] + direction LR + I1["模块安装器"] + I2["构建工具"] + end + + UI --> Editor + UI --> Automation + UI --> Tools + UI --> Install + + A1 --> X1 + A2 --> X2 + A3 --> X3 + A4 --> X4 + A5 --> X5 + A6 --> X6 + A7 --> X7 +``` PyBreeze 采用模块化架构: @@ -131,6 +203,8 @@ PyBreeze UI (PySide6) │ ├── AI 代码审查客户端 │ ├── CoT 提示词编辑器 │ ├── Skill 提示词编辑器 +│ ├── Skill Send GUI +│ ├── 架构图编辑器(WYSIWYG、Mermaid 导入、PNG/SVG 导出) │ └── JupyterLab 集成 └── 安装菜单 ├── 自动化模块安装器 @@ -272,8 +346,9 @@ PyBreeze/ │ │ └── process_executor/python_task_process_manager.py │ ├── extend_multi_language/ # 内置翻译(英语、繁体中文) │ ├── pybreeze_ui/ -│ │ ├── editor_main/ # 主窗口(扩展 JEditor) -│ │ ├── connect_gui/ssh/ # SSH 客户端组件 +│ │ ├── editor_main/ # 主窗口(扩展 JEditor)+ 文件树右键菜单 +│ │ ├── connect_gui/ssh/ # SSH 客户端组件(TOFU host key 验证) +│ │ ├── diagram_editor/ # WYSIWYG 架构图编辑器 │ │ ├── extend_ai_gui/ # AI 代码审查与提示词编辑器 │ │ ├── jupyter_lab_gui/ # JupyterLab 集成 │ │ ├── menu/ # 菜单栏构建 diff --git a/README/README_zh-TW.md b/README/README_zh-TW.md index 1320edc..ac12586 100644 --- a/README/README_zh-TW.md +++ b/README/README_zh-TW.md @@ -68,6 +68,14 @@ PyBreeze 不僅僅是一個程式碼編輯器——它是自動化生命週期 - 密碼與私鑰驗證 - 互動式指令執行 - 遠端檔案樹檢視器,支援 CRUD 操作(建立資料夾、重新命名、刪除、上傳、下載) + - 互動式 TOFU host key 驗證,已確認的金鑰會持久化到 `~/.pybreeze/ssh_known_hosts` +- **架構圖編輯器** — 內建的 WYSIWYG 架構圖編輯器: + - 矩形、圓角矩形、橢圓、菱形節點、連線、自由文字 + - 從本地檔案或 URL 插入圖片(URL 下載會做 SSRF 驗證並有大小上限) + - 支援 Mermaid `flowchart` / `graph` 匯入 + - 儲存/開啟為 `.diagram.json`,匯出為 PNG 或 SVG + - Undo/redo、對齊、分佈、Grid、Snap、Zoom 控制 +- **檔案樹右鍵選單** — 在專案檔案樹中對任何檔案或資料夾按右鍵,可建立檔案/資料夾、重新命名、刪除、複製絕對或相對路徑、在系統檔案管理器中開啟。重新命名或刪除目前已開在編輯器分頁中的檔案時,分頁會同步更新。 - **套件管理器** — 直接從 IDE 選單安裝自動化模組和建構工具,無需離開編輯器。 - **整合文件** — 從選單列快速存取每個自動化模組的文件和 GitHub 頁面。 @@ -81,6 +89,7 @@ PyBreeze 不僅僅是一個程式碼編輯器——它是自動化生命週期 - 逐步分析 - 摘要生成 - **Skill 提示詞編輯器** — 定義和管理可重複使用的技能型提示詞(程式碼解說、程式碼審查範本),可傳送至 LLM API。 +- **Skill Send GUI** — 在獨立的分頁或停靠面板中選擇技能提示詞範本、視需要編輯提示詞內容、傳送到 LLM API 端點並檢視回應。 ### 插件系統 @@ -107,7 +116,70 @@ IDE 介面支援多種語言: ## 架構設計 -![架構圖](../architecture_diagram/AutomationEditorArchitectureDiagram.drawio.png) +```mermaid +flowchart TB + UI["PyBreeze UI · PySide6"] + + subgraph Editor["JEditor 基礎編輯器"] + direction LR + E1["程式碼編輯器 + 分頁"] + E2["檔案樹"] + E3["語法高亮"] + E4["插件系統"] + end + + subgraph Automation["自動化選單"] + direction LR + A1["APITestka"] + A2["AutoControl"] + A3["WebRunner"] + A4["LoadDensity"] + A5["FileAutomation"] + A6["MailThunder"] + A7["TestPioneer"] + end + + subgraph Executors["子行程執行器 · TaskProcessManager"] + direction LR + X1["je_api_testka"] + X2["je_auto_control"] + X3["je_web_runner"] + X4["je_load_density"] + X5["automation-file"] + X6["je-mail-thunder"] + X7["test_pioneer"] + end + + subgraph Tools["工具"] + direction LR + T1["SSH · paramiko"] + T2["AI 程式碼審查"] + T3["CoT 提示詞編輯器"] + T4["Skill 提示詞編輯器"] + T5["Skill Send GUI"] + T6["架構圖編輯器"] + T7["JupyterLab"] + end + + subgraph Install["安裝選單"] + direction LR + I1["模組安裝器"] + I2["建構工具"] + end + + UI --> Editor + UI --> Automation + UI --> Tools + UI --> Install + + A1 --> X1 + A2 --> X2 + A3 --> X3 + A4 --> X4 + A5 --> X5 + A6 --> X6 + A7 --> X7 +``` PyBreeze 採用模組化架構: @@ -131,6 +203,8 @@ PyBreeze UI (PySide6) │ ├── AI 程式碼審查用戶端 │ ├── CoT 提示詞編輯器 │ ├── Skill 提示詞編輯器 +│ ├── Skill Send GUI +│ ├── 架構圖編輯器(WYSIWYG、Mermaid 匯入、PNG/SVG 匯出) │ └── JupyterLab 整合 └── 安裝選單 ├── 自動化模組安裝器 @@ -272,8 +346,9 @@ PyBreeze/ │ │ └── process_executor/python_task_process_manager.py │ ├── extend_multi_language/ # 內建翻譯(英文、繁體中文) │ ├── pybreeze_ui/ -│ │ ├── editor_main/ # 主視窗(擴展 JEditor) -│ │ ├── connect_gui/ssh/ # SSH 用戶端元件 +│ │ ├── editor_main/ # 主視窗(擴展 JEditor)+ 檔案樹右鍵選單 +│ │ ├── connect_gui/ssh/ # SSH 用戶端元件(TOFU host key 驗證) +│ │ ├── diagram_editor/ # WYSIWYG 架構圖編輯器 │ │ ├── extend_ai_gui/ # AI 程式碼審查與提示詞編輯器 │ │ ├── jupyter_lab_gui/ # JupyterLab 整合 │ │ ├── menu/ # 選單列建構 diff --git a/docs/source/Eng/menu_tools.rst b/docs/source/Eng/menu_tools.rst index b4dca9c..2344505 100644 --- a/docs/source/Eng/menu_tools.rst +++ b/docs/source/Eng/menu_tools.rst @@ -1,9 +1,10 @@ Tools Menu ========== -The **Tools** menu provides access to SSH client and AI-powered development tools. -Each tool can be opened either as a **Tab** (in the main tab widget) or as a -**Dock** (a floating/dockable panel). +The **Tools** menu provides access to the SSH client, AI-powered development +tools, and the built-in WYSIWYG architecture-diagram editor. Each tool can be +opened either as a **Tab** (in the main tab widget) or as a **Dock** (a +floating/dockable panel). SSH --- @@ -46,6 +47,66 @@ Skill Send GUI Tab / Dock Opens the Skill Prompt Sender interface for sending prompts to an LLM API and viewing responses. See :doc:`ai_tools` for full details. +Diagram Editor +-------------- + +Diagram Editor Tab / Dock +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Opens the built-in WYSIWYG architecture-diagram editor. Use it to sketch +flowcharts and architecture diagrams directly inside PyBreeze without +switching to an external tool. + +Drawing tools +""""""""""""" + +- **Select** -- pick, move, multi-select with rubber-band +- **Rectangle / Rounded Rectangle / Ellipse / Diamond** -- node shapes +- **Connection** -- connect two nodes with a labelled line +- **Text** -- free-floating text annotation +- **Image (file)** -- insert a local image file +- **Image (URL)** -- download and insert an image from a URL (validated + against private/loopback IP ranges and capped at 20 MB to prevent SSRF) + +File operations +""""""""""""""" + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Action + - Description + * - **New** + - Discards the current diagram (with confirmation if non-empty). + * - **Open** + - Loads a previously saved ``.diagram.json`` file. + * - **Save** / **Save As** (``Ctrl+S`` / ``Ctrl+Shift+S``) + - Saves the diagram as ``.diagram.json``. + * - **Import Mermaid** + - Pastes Mermaid ``flowchart`` / ``graph`` source and converts it to + editable nodes and edges. + * - **Export PNG / SVG** + - Renders the canvas to a raster (PNG) or vector (SVG) image. + +Editing helpers +""""""""""""""" + +- **Undo / Redo** (``Ctrl+Z`` / ``Ctrl+Y``) -- full undo stack with named + commands (Add, Move, Delete, Import, etc.) +- **Copy / Paste / Duplicate / Select All** -- standard shortcuts plus + ``Ctrl+D`` to duplicate selected items +- **Align** -- align selection by left, right, top, bottom, horizontal + centre, or vertical centre +- **Distribute** -- distribute three or more selected items evenly + horizontally or vertically +- **Grid** -- toggle background grid rendering +- **Snap** -- snap node positions to grid while dragging +- **Property Panel** (right side) -- edit text, colours, line width, + shape, and connection style of the selected item +- **Zoom** -- zoom in/out (``Ctrl+=`` / ``Ctrl+-``), reset to 100% + (``Ctrl+0``), or fit-to-content + Tab vs. Dock ------------ diff --git a/docs/source/Eng/ui_overview.rst b/docs/source/Eng/ui_overview.rst index bac6d1c..e791c58 100644 --- a/docs/source/Eng/ui_overview.rst +++ b/docs/source/Eng/ui_overview.rst @@ -25,7 +25,7 @@ The menu bar includes these top-level menus (from left to right): - **UI Style** -- Theme switching - **Automation** -- All automation module menus (AutoControl, APITestka, WebRunner, etc.) - **Install** -- Install automation packages and build tools -- **Tools** -- SSH client, AI tools +- **Tools** -- SSH client, AI tools, diagram editor - **Plugins** -- Plugin browser and loaded plugins - **Run With** -- Run files with different compilers/interpreters @@ -37,7 +37,38 @@ directory. You can: - Browse files and folders - Double-click to open files in the editor -- Right-click for context menu options +- Right-click any file or folder to access the context menu (see below) + +File Tree Context Menu +"""""""""""""""""""""" + +Right-clicking the file tree opens a context menu with the following actions: + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Action + - Description + * - **New File** + - Prompts for a name and creates an empty file in the clicked directory + (or the directory containing the clicked file). + * - **New Folder** + - Prompts for a name and creates a new directory. + * - **Rename** + - Renames the selected file or folder. If the file is currently open in + an editor tab, the tab title and the editor's stored path are updated + to match. + * - **Delete** + - Deletes the selected file or folder after a confirmation dialog. If + the file is open in an editor tab, the tab is closed first. + * - **Copy Path** + - Copies the absolute path of the selected item to the clipboard. + * - **Copy Relative Path** + - Copies the path relative to the file tree's root directory. + * - **Reveal in Explorer** + - Opens the selected item's containing folder in the platform file + manager (Explorer on Windows, Finder on macOS, ``xdg-open`` on Linux). Code Editor (Tab Widget) ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -82,6 +113,7 @@ arrange them freely around the main window: - CoT Prompt Editor Dock - Skill Prompt Editor Dock - Skill Send GUI Dock +- Diagram Editor Dock Dock widgets can be dragged, resized, and snapped to any edge of the main window. diff --git a/docs/source/Zh/menu_tools.rst b/docs/source/Zh/menu_tools.rst index 04c0adf..969e8f5 100644 --- a/docs/source/Zh/menu_tools.rst +++ b/docs/source/Zh/menu_tools.rst @@ -1,7 +1,7 @@ Tools 選單 ========== -**Tools** 選單提供 SSH 用戶端和 AI 開發工具的存取。 +**Tools** 選單提供 SSH 用戶端、AI 開發工具,以及內建的 WYSIWYG 架構圖編輯器。 每個工具都可以作為 **分頁**(在主分頁元件中)或 **停靠面板**(浮動/可停靠面板)開啟。 SSH @@ -44,6 +44,60 @@ Skill Send GUI Tab / Dock 開啟技能提示詞傳送介面,用於將提示詞發送到 LLM API 並查看回應。 詳細資訊請參閱 :doc:`ai_tools`。 +架構圖編輯器 +------------ + +Diagram Editor Tab / Dock +^^^^^^^^^^^^^^^^^^^^^^^^^ + +開啟內建的 WYSIWYG 架構圖編輯器,可直接在 PyBreeze 中繪製流程圖與架構圖, +不需要切換到外部工具。 + +繪圖工具 +"""""""" + +- **選取(Select)** -- 點選、搬移、橡皮筋多選 +- **矩形 / 圓角矩形 / 橢圓 / 菱形** -- 節點形狀 +- **連線(Connection)** -- 將兩個節點以可加標籤的連線串接 +- **文字(Text)** -- 浮動文字註記 +- **圖片(檔案)** -- 插入本地圖片檔 +- **圖片(URL)** -- 從 URL 下載並插入圖片(會驗證 + 目標 IP 不在 private/loopback 範圍,並限制 20 MB 上限以防止 SSRF) + +檔案操作 +"""""""" + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - 操作 + - 說明 + * - **New** + - 清除目前圖形(畫布非空時會跳出確認)。 + * - **Open** + - 載入先前儲存的 ``.diagram.json`` 檔案。 + * - **Save / Save As** (``Ctrl+S`` / ``Ctrl+Shift+S``) + - 將圖形儲存為 ``.diagram.json``。 + * - **Import Mermaid** + - 貼上 Mermaid ``flowchart`` / ``graph`` 原始碼,轉換為可編輯的節點與邊。 + * - **Export PNG / SVG** + - 將畫布輸出為點陣圖(PNG)或向量圖(SVG)。 + +編輯輔助 +"""""""" + +- **Undo / Redo** (``Ctrl+Z`` / ``Ctrl+Y``) -- 完整的 undo stack,含具名指令 + (新增、搬移、刪除、Import 等) +- **Copy / Paste / Duplicate / Select All** -- 標準快捷鍵;``Ctrl+D`` 可複製選取項目 +- **對齊(Align)** -- 將選取項目以左、右、上、下、水平置中、垂直置中對齊 +- **分佈(Distribute)** -- 三個以上選取項目可水平或垂直平均分佈 +- **Grid** -- 切換背景格線 +- **Snap** -- 拖曳節點時對齊格線 +- **屬性面板(右側)** -- 編輯選取項目的文字、顏色、線寬、形狀、連線樣式 +- **Zoom** -- 放大/縮小 (``Ctrl+=`` / ``Ctrl+-``)、重設 100% + (``Ctrl+0``)、Fit-to-content + 分頁 vs. 停靠面板 ------------------ diff --git a/docs/source/Zh/ui_overview.rst b/docs/source/Zh/ui_overview.rst index 6dfb89c..5772550 100644 --- a/docs/source/Zh/ui_overview.rst +++ b/docs/source/Zh/ui_overview.rst @@ -25,7 +25,7 @@ SSH、AI 工具、外掛等選單。 - **UI Style** -- 主題切換 - **Automation** -- 所有自動化模組選單(AutoControl、APITestka、WebRunner 等) - **Install** -- 安裝自動化套件和建置工具 -- **Tools** -- SSH 用戶端、AI 工具 +- **Tools** -- SSH 用戶端、AI 工具、架構圖編輯器 - **Plugins** -- 外掛瀏覽器和已載入外掛 - **Run With** -- 使用不同編譯器/直譯器執行檔案 @@ -36,7 +36,37 @@ SSH、AI 工具、外掛等選單。 - 瀏覽檔案和資料夾 - 雙擊在編輯器中開啟檔案 -- 右鍵開啟功能選單 +- 右鍵任何檔案或資料夾以開啟功能選單(詳見下方) + +檔案樹右鍵選單 +"""""""""""""" + +在檔案樹中按右鍵會跳出包含以下動作的選單: + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - 動作 + - 說明 + * - **New File** + - 跳出輸入框詢問檔名,在按右鍵的目錄下(或被點擊檔案所在目錄) + 建立空檔案。 + * - **New Folder** + - 跳出輸入框詢問資料夾名稱,建立新目錄。 + * - **Rename** + - 重新命名選取的檔案或資料夾。若該檔案正以分頁形式開啟在編輯器中, + 分頁標題與編輯器內部的路徑會同步更新。 + * - **Delete** + - 顯示確認對話框後刪除選取的檔案或資料夾。若該檔案正以分頁開啟, + 會先關閉分頁。 + * - **Copy Path** + - 將選取項目的絕對路徑複製到剪貼簿。 + * - **Copy Relative Path** + - 複製相對於檔案樹根目錄的相對路徑。 + * - **Reveal in Explorer** + - 在系統檔案管理器中開啟選取項目所在資料夾(Windows 的檔案總管、 + macOS 的 Finder、Linux 的 ``xdg-open``)。 程式碼編輯器(分頁元件) ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -79,6 +109,7 @@ SSH、AI 工具、外掛等選單。 - CoT 提示詞編輯器停靠面板 - Skill 提示詞編輯器停靠面板 - Skill 傳送 GUI 停靠面板 +- 架構圖編輯器停靠面板 停靠面板可以拖曳、調整大小,並固定到主視窗的任何邊緣。 diff --git a/pybreeze/extend/process_executor/process_executor_utils.py b/pybreeze/extend/process_executor/process_executor_utils.py index c968ca6..3be5fbf 100644 --- a/pybreeze/extend/process_executor/process_executor_utils.py +++ b/pybreeze/extend/process_executor/process_executor_utils.py @@ -43,25 +43,50 @@ def start_process( send_mail: bool = False, program_buffer: int = 1024000 ): - # Code window init + process = _build_task_process(main_window, send_mail, program_buffer) + process.start_test_process( + package, + exec_str=test_format_code, + ) + + +def build_process_from_file( + main_window: PyBreezeMainWindow, + package: str, + file_path: str, + send_mail: bool = False, + program_buffer: int = 1024000, +): + """Run ``package`` against an action JSON file path. + + Bypasses the ``--execute_str`` cmdline path so large scripts cannot trip + the Windows ~32K argv limit. Useful for batch / multi-file flows where + the file is already on disk. + """ + try: + process = _build_task_process(main_window, send_mail, program_buffer) + process.start_test_process_file(package, file_path) + except ITETestExecutorException as error: + pybreeze_logger.error(repr(error)) + + +def _build_task_process( + main_window: PyBreezeMainWindow, + send_mail: bool, + program_buffer: int, +) -> TaskProcessManager: code_window = CodeWindow() main_window.current_run_code_window.append(code_window) main_window.clear_code_result() - # Process init if send_mail: - process = TaskProcessManager( + return TaskProcessManager( main_window=code_window, task_done_trigger_function=send_after_test, program_buffer_size=program_buffer, - program_encoding=main_window.encoding + program_encoding=main_window.encoding, ) - else: - process = TaskProcessManager( - code_window, - program_buffer_size=program_buffer, - program_encoding=main_window.encoding - ) - process.start_test_process( - package, - exec_str=test_format_code, + return TaskProcessManager( + code_window, + program_buffer_size=program_buffer, + program_encoding=main_window.encoding, ) diff --git a/pybreeze/extend/process_executor/python_task_process_manager.py b/pybreeze/extend/process_executor/python_task_process_manager.py index c62f871..6be4839 100644 --- a/pybreeze/extend/process_executor/python_task_process_manager.py +++ b/pybreeze/extend/process_executor/python_task_process_manager.py @@ -83,30 +83,41 @@ def start_test_process(self, package: str, exec_str: str): "--execute_str", exec_str ] + self._spawn_and_pump(package, args) + + def start_test_process_file(self, package: str, file_path: str): + # Pass the action JSON as a path so we never hit the Windows ~32K + # command-line cap when scripts are large. Caller owns the file. + self.renew_path() + args = [ + str(self.compiler_path), + "-m", + package, + "--execute_file", + str(file_path), + ] + self._spawn_and_pump(package, args) + + def _spawn_and_pump(self, package: str, args: list) -> None: # Launch user-authored automation script in a child interpreter. # Argument list is validated upstream; shell=False, no user string ever # reaches a shell. nosec B603 — intentional local process execution. self.process = subprocess.Popen( # nosec B603 # nosemgrep # noqa: S603 args, - stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) self.still_run_program = True - # program output message queue thread self.read_program_output_from_thread = Thread( target=self.read_program_output_from_process, daemon=True ) self.read_program_output_from_thread.start() - # program error message queue thread self.read_program_error_output_from_thread = Thread( target=self.read_program_error_output_from_process, daemon=True ) self.read_program_error_output_from_thread.start() - # start Pyside update - # start timer self.main_window.setWindowTitle(package) self.main_window.show() self.timer = QTimer(self.main_window) diff --git a/pybreeze/extend/process_executor/web_runner/web_runner_process.py b/pybreeze/extend/process_executor/web_runner/web_runner_process.py index 3285c59..64e49d6 100644 --- a/pybreeze/extend/process_executor/web_runner/web_runner_process.py +++ b/pybreeze/extend/process_executor/web_runner/web_runner_process.py @@ -2,7 +2,9 @@ from typing import TYPE_CHECKING -from pybreeze.extend.process_executor.process_executor_utils import build_process +from pybreeze.extend.process_executor.process_executor_utils import ( + build_process, build_process_from_file, +) if TYPE_CHECKING: from pybreeze.pybreeze_ui.editor_main.main_ui import PyBreezeMainWindow @@ -35,12 +37,10 @@ def call_web_runner_test_multi_file( need_to_execute_list = ask_and_get_dir_files_as_list(main_window) if need_to_execute_list is not None and len(need_to_execute_list) > 0: for execute_file in need_to_execute_list: - with open(execute_file, encoding="utf-8") as test_script_json: - call_web_runner_test( - main_window, - test_script_json.read(), - program_buffer - ) + build_process_from_file( + main_window, "je_web_runner", execute_file, + False, program_buffer, + ) except Exception as error: pybreeze_logger.error(f"web runner multi file error: {error}") @@ -53,11 +53,9 @@ def call_web_runner_test_multi_file_and_send( need_to_execute_list = ask_and_get_dir_files_as_list(main_window) if need_to_execute_list is not None and len(need_to_execute_list) > 0: for execute_file in need_to_execute_list: - with open(execute_file, encoding="utf-8") as test_script_json: - call_web_runner_test_with_send( - main_window, - test_script_json.read(), - program_buffer - ) + build_process_from_file( + main_window, "je_web_runner", execute_file, + True, program_buffer, + ) except Exception as error: pybreeze_logger.error(f"web runner multi file and send error: {error}") diff --git a/pybreeze/pybreeze_ui/syntax/syntax_keyword.py b/pybreeze/pybreeze_ui/syntax/syntax_keyword.py index 782b711..475135b 100644 --- a/pybreeze/pybreeze_ui/syntax/syntax_keyword.py +++ b/pybreeze/pybreeze_ui/syntax/syntax_keyword.py @@ -50,40 +50,309 @@ ] web_runner_keys: list = [ - "WR_get_webdriver_manager", "WR_change_index_of_webdriver", "WR_quit", "WR_SaveTestObject", - "WR_CleanTestObject", "WR_set_driver", "WR_set_webdriver_options_capability", "WR_find_element", - "WR_find_elements", "WR_implicitly_wait", "WR_explict_wait", "WR_to_url", - "WR_forward", "WR_back", "WR_refresh", "WR_switch", "WR_set_script_timeout", "WR_set_page_load_timeout", - "WR_get_cookies", "WR_get_cookie", "WR_add_cookie", "WR_delete_cookie", "WR_delete_all_cookies", - "WR_execute", "WR_execute_script", "WR_execute_async_script", "WR_move_to_element", - "WR_move_to_element_with_offset", "WR_drag_and_drop", "WR_drag_and_drop_offset", "WR_perform", - "WR_reset_actions", "WR_left_click", "WR_left_click_and_hold", "WR_right_click", - "WR_left_double_click", "WR_release", "WR_press_key", "WR_release_key", - "WR_move_by_offset", "WR_pause", "WR_send_keys", "WR_send_keys_to_element", "WR_scroll", - "WR_check_current_webdriver", "WR_maximize_window", "WR_fullscreen_window", "WR_minimize_window", - "WR_set_window_size", "WR_set_window_position", "WR_get_window_position", - "WR_get_window_rect", "WR_set_window_rect", "WR_get_screenshot_as_png", "WR_get_screenshot_as_base64", - "WR_get_log", "WR_single_quit", "WR_element_submit", "WR_element_clear", "WR_element_get_property", + # ===== Action commands (WR_*) ===== + # webdriver manager + "WR_get_webdriver_manager", "WR_change_index_of_webdriver", "WR_quit", + # test object + "WR_SaveTestObject", "WR_CleanTestObject", + # webdriver wrapper + "WR_set_driver", "WR_set_webdriver_options_capability", + "WR_find_element", "WR_find_elements", + "WR_implicitly_wait", "WR_explict_wait", "WR_sleep", + "WR_to_url", "WR_forward", "WR_back", "WR_refresh", "WR_switch", + "WR_set_script_timeout", "WR_set_page_load_timeout", + "WR_get_cookies", "WR_get_cookie", "WR_add_cookie", + "WR_delete_cookie", "WR_delete_all_cookies", + "WR_execute", "WR_execute_script", "WR_execute_async_script", + "WR_move_to_element", "WR_move_to_element_with_offset", + "WR_drag_and_drop", "WR_drag_and_drop_offset", + "WR_perform", "WR_reset_actions", + "WR_left_click", "WR_left_click_and_hold", "WR_right_click", "WR_left_double_click", + "WR_release", "WR_press_key", "WR_release_key", + "WR_move_by_offset", "WR_pause", + "WR_send_keys", "WR_send_keys_to_element", "WR_scroll", + "WR_check_current_webdriver", + "WR_maximize_window", "WR_fullscreen_window", "WR_minimize_window", + "WR_set_window_size", "WR_set_window_position", + "WR_get_window_position", "WR_get_window_rect", "WR_set_window_rect", + "WR_get_screenshot_as_png", "WR_get_screenshot_as_base64", + "WR_get_log", "WR_single_quit", + # web element + "WR_element_submit", "WR_element_clear", "WR_element_get_property", "WR_element_get_dom_attribute", "WR_element_get_attribute", - "WR_element_is_selected", "WR_element_is_enabled", "WR_input_to_element", "WR_click_element", - "WR_element_is_displayed", "WR_element_value_of_css_property", "WR_element_screenshot", - "WR_element_change_web_element", "WR_element_check_current_web_element", "WR_element_get_select", - "WR_set_record_enable", "WR_generate_html", "WR_generate_html_report", "WR_generate_json", - "WR_generate_json_report", "WR_generate_xml", "WR_generate_xml_report", - "WR_execute_action", "WR_execute_files", "WR_add_package_to_executor", - "WR_add_package_to_callback_executor", "WR_scheduler_event_trigger", "WR_remove_blocking_scheduler_job", - "WR_remove_nonblocking_scheduler_job", "WR_start_blocking_scheduler", "WR_start_nonblocking_scheduler", - "WR_start_all_scheduler", "WR_shutdown_blocking_scheduler", "WR_shutdown_nonblocking_scheduler", - "web_element_wrapper", "set_webdriver_options_argument", "SchedulerManager", - "webdriver_wrapper", "get_webdriver_manager", - "get_desired_capabilities", "get_desired_capabilities_keys", "add_command_to_executor", - "execute_action", "execute_files", "executor", + "WR_element_is_selected", "WR_element_is_enabled", + "WR_input_to_element", "WR_click_element", + "WR_element_is_displayed", "WR_element_value_of_css_property", + "WR_element_screenshot", "WR_element_change_web_element", + "WR_element_check_current_web_element", "WR_element_get_select", + "WR_element_select_by_value", "WR_element_select_by_index", + "WR_element_select_by_visible_text", + # record / report + "WR_set_record_enable", + "WR_generate_html", "WR_generate_html_report", + "WR_generate_json", "WR_generate_json_report", + "WR_generate_xml", "WR_generate_xml_report", + "WR_generate_junit_xml", "WR_generate_junit_xml_report", + "WR_generate_allure", "WR_generate_allure_report", + "WR_generate_all_reports", "WR_report_expected_paths", + # execute / validate + "WR_execute_action", "WR_execute_files", + "WR_validate_action_json", "WR_validate_action_file", + # environment configuration + "WR_load_env", "WR_get_env", "WR_expand_env_in_action", + # data-driven + "WR_load_dataset_csv", "WR_load_dataset_json", + "WR_expand_with_row", "WR_run_with_dataset", + # failure screenshot / retry / arbitrary-script gate + "WR_set_failure_screenshot_dir", "WR_set_retry_policy", + "WR_set_allow_arbitrary_script", + # self-healing locators + "WR_register_fallback_locator", "WR_register_fallback_locators", + "WR_clear_fallback_locators", "WR_find_with_healing", "WR_pw_find_with_healing", + # HTTP API testing + "WR_http_request", "WR_http_get", "WR_http_post", "WR_http_put", + "WR_http_patch", "WR_http_delete", + "WR_http_assert_status", "WR_http_assert_json_contains", + # CDP + "WR_cdp", "WR_pw_cdp", "WR_pw_cdp_reset_sessions", + # network throttling + "WR_throttle", "WR_throttle_clear", + "WR_pw_throttle", "WR_pw_throttle_clear", "WR_throttle_presets", + # faker + "WR_faker_seed", "WR_faker", "WR_faker_email", "WR_faker_name", + "WR_faker_first_name", "WR_faker_last_name", "WR_faker_phone", + "WR_faker_address", "WR_faker_uuid", "WR_faker_credit_card", + "WR_faker_url", "WR_faker_user_agent", "WR_faker_password", "WR_faker_text", + # browser extensions + "WR_chrome_options_with_extension", "WR_pw_extension_args", + # shadow DOM / iframe + "WR_shadow_query", "WR_pw_shadow_query", "WR_pw_shadow_selector", + "WR_iframe_switch_chain", "WR_iframe_back_to_default", + "WR_pw_frame_locator_chain", + # file upload / download + "WR_upload_file", "WR_pw_upload_file", + "WR_wait_for_download", "WR_list_new_downloads", "WR_snapshot_directory", + # action linter / migration / schema / docs + "WR_lint_action", "WR_lint_action_file", "WR_lint_severity_counts", + "WR_migrate_action", "WR_migrate_action_file", "WR_migrate_directory", + "WR_build_action_schema", "WR_export_action_schema", + "WR_build_command_reference", "WR_export_command_reference", "WR_list_commands", + # tracing + "WR_set_action_span_factory", + # database validation + "WR_db_query", "WR_db_assert_count", "WR_db_assert_value", + "WR_db_assert_exists", "WR_db_assert_empty", + # scheduler + "WR_schedule", "WR_run_scheduler_for", "WR_run_scheduler_forever", + "WR_stop_scheduler", "WR_scheduler_counts", "WR_reset_scheduler", + # multi-user matrix + "WR_run_for_users", + # failure classifier + "WR_classify_error", "WR_classify_failure", "WR_classify_failures", + # replay studio + "WR_build_replay_html", "WR_export_replay_studio", + # OAuth2 / OIDC + "WR_oauth_client_credentials", "WR_oauth_password_grant", + "WR_oauth_refresh_token", "WR_oauth_get_cached", + "WR_oauth_clear_cache", "WR_oauth_bearer_header", + # factories + "WR_user_factory", "WR_order_factory", "WR_product_factory", + # testcontainers + "WR_tc_postgres", "WR_tc_redis", "WR_tc_generic", + "WR_tc_stop", "WR_tc_cleanup_all", "WR_tc_started_count", + # live dashboard + "WR_dashboard_start", "WR_dashboard_stop", + # sharding + "WR_parse_shard_spec", "WR_partition", "WR_partition_with_spec", + # Appium + "WR_appium_start", "WR_appium_quit", + "WR_appium_android_caps", "WR_appium_ios_caps", + # LLM scaffolds + "WR_llm_set_callable", "WR_llm_has_callable", + "WR_llm_suggest_locator", "WR_llm_generate_actions", + "WR_llm_self_heal_locator", + # storage (Selenium) + "WR_local_storage_set", "WR_local_storage_get", "WR_local_storage_remove", + "WR_local_storage_clear", "WR_local_storage_all", + "WR_session_storage_set", "WR_session_storage_get", "WR_session_storage_clear", + "WR_indexed_db_drop", + # storage (Playwright) + "WR_pw_local_storage_set", "WR_pw_local_storage_get", "WR_pw_local_storage_remove", + "WR_pw_local_storage_clear", "WR_pw_local_storage_all", + "WR_pw_session_storage_set", "WR_pw_session_storage_get", + "WR_pw_session_storage_clear", "WR_pw_indexed_db_drop", + # service worker / cache + "WR_sw_unregister", "WR_sw_clear_caches", "WR_sw_bypass", + "WR_pw_sw_unregister", "WR_pw_sw_clear_caches", "WR_pw_sw_bypass", + # console / network event capture (Playwright) + "WR_pw_event_capture_start", "WR_pw_event_capture_stop", + "WR_pw_event_capture_clear", + "WR_pw_console_messages", "WR_pw_network_responses", + "WR_pw_assert_no_console_errors", + "WR_pw_assert_no_5xx", "WR_pw_assert_no_4xx_or_5xx", + # secrets / security headers + "WR_scan_secrets", "WR_scan_secrets_file", "WR_assert_no_secrets", + "WR_audit_security_headers", "WR_audit_security_headers_url", + # perf metrics + "WR_perf_collect", "WR_pw_perf_collect", "WR_perf_assert_within", + # snapshot testing + "WR_match_snapshot", "WR_update_snapshot", "WR_delete_snapshot", + # HAR diff + "WR_diff_har", "WR_diff_har_files", + # tag / dependency + "WR_read_metadata", "WR_filter_paths", + "WR_read_depends_on", "WR_build_dependency_graph", + "WR_topological_order", "WR_skip_dependents_of_failed", + # run ledger / flakiness + "WR_ledger_record_run", "WR_ledger_failed_files", + "WR_ledger_passed_files", "WR_ledger_clear", + "WR_flakiness_stats", "WR_flaky_paths", + # A/B run mode + "WR_run_ab", "WR_diff_ab_records", + # cloud grid (BrowserStack / Sauce Labs / LambdaTest) + "WR_browserstack_capabilities", "WR_saucelabs_capabilities", + "WR_lambdatest_capabilities", + "WR_connect_browserstack", "WR_connect_saucelabs", "WR_connect_lambdatest", + "WR_start_remote_driver", + # JIRA / TestRail + "WR_jira_create_issue", "WR_jira_create_failure_issues", + "WR_testrail_send_results", "WR_testrail_results_from_pairs", + "WR_testrail_close_run", + # GitHub Actions annotations + "WR_gh_format_error", "WR_gh_emit_failures", "WR_gh_emit_from_junit_xml", + # Lighthouse / Locust + "WR_lighthouse_run", "WR_lighthouse_assert_scores", + "WR_locust_run", "WR_locust_build_user_class", + # accessibility (axe-core) + "WR_a11y_load_axe", "WR_a11y_run_audit", + "WR_pw_a11y_run_audit", "WR_a11y_summarise", + # webhook / Slack + "WR_summarise_run", "WR_notify_webhook", + "WR_notify_slack", "WR_notify_run_summary", + # POM generator + "WR_generate_pom_from_url", "WR_generate_pom_from_html", "WR_write_pom_to_file", + # visual regression + "WR_visual_capture_baseline", "WR_visual_compare", + # browser recorder + "WR_recorder_start", "WR_recorder_stop", + "WR_recorder_pull_events", "WR_recorder_save", + # Playwright — page level + "WR_pw_launch", "WR_pw_quit", + "WR_pw_start_har_recording", "WR_pw_stop_har_recording", + "WR_pw_route_mock", "WR_pw_route_mock_json", + "WR_pw_route_unmock", "WR_pw_route_clear", + "WR_pw_emulate", "WR_pw_stop_emulate", "WR_pw_list_devices", + "WR_pw_set_geolocation", "WR_pw_grant_permissions", "WR_pw_clear_permissions", + "WR_pw_set_timezone", + "WR_pw_clock_install", "WR_pw_clock_set_time", "WR_pw_clock_run_for", + "WR_pw_set_locale", + "WR_pw_to_url", "WR_pw_forward", "WR_pw_back", "WR_pw_refresh", + "WR_pw_url", "WR_pw_title", "WR_pw_content", + "WR_pw_set_default_timeout", "WR_pw_set_default_navigation_timeout", + "WR_pw_new_page", "WR_pw_switch_to_page", + "WR_pw_close_page", "WR_pw_page_count", + "WR_pw_find_element", "WR_pw_find_elements", + "WR_pw_find_element_with_test_object_record", + "WR_pw_find_elements_with_test_object_record", + "WR_pw_save_test_object_to_selector", + "WR_pw_click", "WR_pw_dblclick", "WR_pw_hover", + "WR_pw_fill", "WR_pw_type_text", "WR_pw_press", + "WR_pw_check", "WR_pw_uncheck", "WR_pw_select_option", + "WR_pw_drag_and_drop", "WR_pw_evaluate", + "WR_pw_get_cookies", "WR_pw_add_cookies", "WR_pw_clear_cookies", + "WR_pw_screenshot", "WR_pw_screenshot_bytes", + "WR_pw_wait_for_selector", "WR_pw_wait_for_load_state", + "WR_pw_wait_for_timeout", "WR_pw_wait_for_url", + "WR_pw_set_viewport_size", "WR_pw_viewport_size", + "WR_pw_mouse_click", "WR_pw_mouse_move", + "WR_pw_mouse_down", "WR_pw_mouse_up", + "WR_pw_keyboard_press", "WR_pw_keyboard_type", + "WR_pw_keyboard_down", "WR_pw_keyboard_up", + # Playwright — element level + "WR_pw_element_click", "WR_pw_element_dblclick", + "WR_pw_element_hover", "WR_pw_element_fill", + "WR_pw_element_type_text", "WR_pw_element_press", + "WR_pw_element_clear", "WR_pw_element_check", "WR_pw_element_uncheck", + "WR_pw_element_select_option", + "WR_pw_element_get_attribute", "WR_pw_element_get_property", + "WR_pw_element_inner_text", "WR_pw_element_inner_html", + "WR_pw_element_is_visible", "WR_pw_element_is_enabled", "WR_pw_element_is_checked", + "WR_pw_element_scroll_into_view", "WR_pw_element_screenshot", + "WR_pw_element_change", + # add package + "WR_add_package_to_executor", "WR_add_package_to_callback_executor", + # naming aliases + "WR_new_driver", "WR_quit_all", "WR_quit_current", + "WR_explicit_wait", "WR_save_test_object", "WR_clear_test_objects", + "WR_find_recorded_element", "WR_find_recorded_elements", + "WR_element_input", "WR_element_click", "WR_element_assert", + + # ===== Python public API (from je_web_runner.__all__) ===== + "web_element_wrapper", "set_webdriver_options_argument", + "webdriver_wrapper_instance", "get_webdriver_manager", + "get_desired_capabilities", "get_desired_capabilities_keys", + "add_command_to_executor", "execute_action", "execute_files", "executor", "generate_html", "generate_html_report", "generate_json", "generate_json_report", "read_action_json", "generate_xml", "generate_xml_report", + "generate_junit_xml", "generate_junit_xml_report", + "generate_allure", "generate_allure_report", "start_web_runner_socket_server", "get_dir_files_as_list", "TestObject", "create_test_object", "get_test_object_type_list", - "test_record_instance", "Keys", "callback_executor", "create_project_dir" + "test_record_instance", "Keys", "callback_executor", "create_project_dir", + # env / data-driven + "load_env", "get_env", "expand_in_action", "EnvConfigError", + "load_dataset_csv", "load_dataset_json", + "expand_with_row", "run_with_dataset", "DataDrivenError", + # self-healing + "HealingError", "HealingRegistry", "healing_registry", + "register_fallback", "register_fallbacks", "clear_fallbacks", + "find_with_healing_selenium", "find_with_healing_playwright", + # HTTP + "http_request", "http_get", "http_post", "http_put", "http_patch", "http_delete", + "http_assert_status", "http_assert_json_contains", "get_last_response", + "HttpAssertionError", + # accessibility / CDP + "AccessibilityError", "load_axe_source", + "selenium_run_audit", "playwright_run_audit", "summarise_violations", + "CDPError", "selenium_cdp", "playwright_cdp", "reset_playwright_cdp_sessions", + # notifier + "summarise_run", "notify_webhook", "notify_slack", + "notify_run_summary", "NotifierError", + # POM / validators + "POMGeneratorError", "extract_elements_from_html", "generate_pom_class", + "generate_pom_from_html", "generate_pom_from_url", "write_pom_to_file", + "validate_action_json", "validate_action_file", "validate_action_files", + # visual regression / recorder + "visual_capture_baseline", "visual_compare_with_baseline", + "recorder_start", "recorder_stop", "recorder_pull_events", + "recorder_events_to_actions", "recorder_save_recording", + # Playwright wrappers + "PlaywrightBackendError", "PlaywrightWrapper", "playwright_wrapper_instance", + "PlaywrightElementWrapper", "playwright_element_wrapper", + "pw_launch", "pw_quit", + "pw_start_har_recording", "pw_stop_har_recording", + "pw_route_mock", "pw_route_mock_json", "pw_route_unmock", "pw_route_clear", + "pw_to_url", "pw_forward", "pw_back", "pw_refresh", + "pw_url", "pw_title", "pw_content", + "pw_set_default_timeout", "pw_set_default_navigation_timeout", + "pw_new_page", "pw_switch_to_page", "pw_close_page", "pw_page_count", + "pw_find_element", "pw_find_elements", + "pw_find_element_with_test_object_record", + "pw_find_elements_with_test_object_record", + "pw_save_test_object_to_selector", + "pw_click", "pw_dblclick", "pw_hover", + "pw_fill", "pw_type_text", "pw_press", + "pw_check", "pw_uncheck", "pw_select_option", "pw_drag_and_drop", + "pw_evaluate", + "pw_get_cookies", "pw_add_cookies", "pw_clear_cookies", + "pw_screenshot", "pw_screenshot_bytes", + "pw_wait_for_selector", "pw_wait_for_load_state", + "pw_wait_for_timeout", "pw_wait_for_url", + "pw_set_viewport_size", "pw_viewport_size", + "pw_mouse_click", "pw_mouse_move", "pw_mouse_down", "pw_mouse_up", + "pw_keyboard_press", "pw_keyboard_type", + "pw_keyboard_down", "pw_keyboard_up", ] load_density_keys: list = [ @@ -107,27 +376,111 @@ ] automation_file_keys: list = [ - "FA_create_file", "FA_copy_file", "FA_rename_file", "FA_remove_file", "FA_copy_all_file_to_dir", - "FA_copy_specify_extension_file", "FA_copy_dir", "FA_create_dir", "FA_remove_dir_tree", - "FA_zip_dir", "FA_zip_file", "FA_zip_info", "FA_zip_file_info", "FA_set_zip_password", "FA_unzip_file", - "FA_read_zip_file", "FA_unzip_all", "FA_drive_later_init", - "FA_drive_search_all_file", "FA_drive_search_field", "FA_drive_search_file_mimetype", - "FA_drive_upload_dir_to_folder", "FA_drive_upload_to_folder", "FA_drive_upload_dir_to_drive", - "FA_drive_upload_to_drive", "FA_drive_add_folder", "FA_drive_share_file_to_anyone", - "FA_drive_share_file_to_domain", "FA_drive_share_file_to_user", "FA_drive_delete_file", - "FA_drive_download_file", "FA_drive_download_file_from_folder", - "FA_execute_action", "FA_execute_files", "FA_add_package_to_executor", - "FA_scheduler_event_trigger", "FA_remove_blocking_scheduler_job", "FA_remove_nonblocking_scheduler_job", - "FA_start_blocking_scheduler", "FA_start_nonblocking_scheduler", "FA_start_all_scheduler", - "FA_shutdown_blocking_scheduler", "FA_shutdown_nonblocking_scheduler", - "copy_file", "rename_file", "remove_file", "copy_all_file_to_dir", "copy_specify_extension_file", - "copy_dir", "create_dir", "remove_dir_tree", "zip_dir", "zip_file", "zip_info", - "zip_file_info", "set_zip_password", "unzip_file", "read_zip_file", - "unzip_all", "driver_instance", "drive_search_all_file", "drive_search_field", "drive_search_file_mimetype", - "drive_upload_dir_to_folder", "drive_upload_to_folder", "drive_upload_dir_to_drive", "drive_upload_to_drive", - "drive_add_folder", "drive_share_file_to_anyone", "drive_share_file_to_domain", "drive_share_file_to_user", - "drive_delete_file", "drive_download_file", "drive_download_file_from_folder", "execute_action", "execute_files", - "add_command_to_executor", "read_action_json", "get_dir_files_as_list", "create_project_dir" + # Core executor + "FA_execute_action", "FA_execute_files", "FA_execute_action_parallel", + "FA_execute_action_dag", "FA_validate", + # Files + "FA_create_file", "FA_copy_file", "FA_rename_file", "FA_remove_file", + "FA_copy_all_file_to_dir", "FA_copy_specify_extension_file", + # Directories + "FA_copy_dir", "FA_create_dir", "FA_remove_dir_tree", "FA_rename_dir", "FA_sync_dir", + # Shell + "FA_run_shell", + # JSON edit + "FA_json_get", "FA_json_set", "FA_json_delete", + # Tar + "FA_create_tar", "FA_extract_tar", + # Zip + "FA_zip_dir", "FA_zip_file", "FA_zip_info", "FA_zip_file_info", + "FA_set_zip_password", "FA_unzip_file", "FA_read_zip_file", "FA_unzip_all", + # Conditional + "FA_if_exists", "FA_if_newer", "FA_if_size_gt", + # Text / encoding + "FA_file_split", "FA_file_merge", "FA_encoding_convert", "FA_line_count", "FA_sed_replace", + # Diff / patch + "FA_diff_files", "FA_diff_dirs", "FA_apply_patch", + # CSV / JSONL + "FA_csv_filter", "FA_csv_to_jsonl", "FA_jsonl_iter", "FA_jsonl_append", + # YAML + "FA_yaml_get", "FA_yaml_set", "FA_yaml_delete", + # Parquet + "FA_parquet_read", "FA_parquet_write", "FA_csv_to_parquet", + # HTTP + "FA_download_file", + # Utils / integrity / crypto + "FA_fast_find", "FA_file_checksum", "FA_verify_checksum", "FA_find_duplicates", + "FA_write_manifest", "FA_verify_manifest", "FA_grep", "FA_rotate_backups", + "FA_copy_between", "FA_encrypt_file", "FA_decrypt_file", "FA_tracing_init", + # Google Drive + "FA_drive_later_init", "FA_drive_search_all_file", "FA_drive_search_field", + "FA_drive_search_file_mimetype", "FA_drive_upload_dir_to_folder", + "FA_drive_upload_to_folder", "FA_drive_upload_dir_to_drive", "FA_drive_upload_to_drive", + "FA_drive_add_folder", "FA_drive_share_file_to_anyone", "FA_drive_share_file_to_domain", + "FA_drive_share_file_to_user", "FA_drive_delete_file", "FA_drive_download_file", + "FA_drive_download_file_from_folder", + # S3 + "FA_s3_later_init", "FA_s3_upload_file", "FA_s3_upload_dir", + "FA_s3_download_file", "FA_s3_delete_object", "FA_s3_list_bucket", + # Azure Blob + "FA_azure_blob_later_init", "FA_azure_blob_upload_file", "FA_azure_blob_upload_dir", + "FA_azure_blob_download_file", "FA_azure_blob_delete_blob", "FA_azure_blob_list_container", + # Dropbox + "FA_dropbox_later_init", "FA_dropbox_upload_file", "FA_dropbox_upload_dir", + "FA_dropbox_download_file", "FA_dropbox_delete_path", "FA_dropbox_list_folder", + # SFTP + "FA_sftp_later_init", "FA_sftp_close", "FA_sftp_upload_file", "FA_sftp_upload_dir", + "FA_sftp_download_file", "FA_sftp_delete_path", "FA_sftp_list_dir", + # FTP + "FA_ftp_later_init", "FA_ftp_close", "FA_ftp_upload_file", "FA_ftp_upload_dir", + "FA_ftp_download_file", "FA_ftp_delete_path", "FA_ftp_list_dir", + # OneDrive + "FA_onedrive_later_init", "FA_onedrive_device_code_login", "FA_onedrive_upload_file", + "FA_onedrive_upload_dir", "FA_onedrive_download_file", "FA_onedrive_delete_item", + "FA_onedrive_list_folder", "FA_onedrive_close", + # Box + "FA_box_later_init", "FA_box_upload_file", "FA_box_upload_dir", "FA_box_download_file", + "FA_box_delete_file", "FA_box_delete_folder", "FA_box_list_folder", + # Triggers + "FA_watch_start", "FA_watch_stop", "FA_watch_stop_all", "FA_watch_list", + # Scheduler + "FA_schedule_add", "FA_schedule_remove", "FA_schedule_remove_all", "FA_schedule_list", + # Progress / cancellation + "FA_progress_list", "FA_progress_cancel", "FA_progress_clear", + # Notifications + "FA_notify_send", "FA_notify_list", + # Public Python API symbols + "copy_file", "rename_file", "remove_file", "copy_all_file_to_dir", + "copy_specify_extension_file", "create_file", + "copy_dir", "create_dir", "remove_dir_tree", "rename_dir", "sync_dir", + "zip_dir", "zip_file", "zip_info", "zip_file_info", "set_zip_password", + "unzip_file", "read_zip_file", "unzip_all", + "driver_instance", "drive_search_all_file", "drive_search_field", + "drive_search_file_mimetype", "drive_upload_dir_to_folder", "drive_upload_to_folder", + "drive_upload_dir_to_drive", "drive_upload_to_drive", "drive_add_folder", + "drive_share_file_to_anyone", "drive_share_file_to_domain", "drive_share_file_to_user", + "drive_delete_file", "drive_download_file", "drive_download_file_from_folder", + "download_file", "validate_http_url", + "execute_action", "execute_action_parallel", "execute_files", "validate_action", + "add_command_to_executor", "read_action_json", "write_action_json", + "get_dir_files_as_list", "create_project_dir", + "ActionExecutor", "ActionRegistry", "CallbackExecutor", "PackageLoader", + "Quota", "retry_on_transient", "safe_join", "is_within", + "executor", "callback_executor", "package_manager", + "build_default_registry", + "GoogleDriveClient", "S3Client", "s3_instance", "register_s3_ops", + "AzureBlobClient", "azure_blob_instance", "register_azure_blob_ops", + "DropboxClient", "dropbox_instance", "register_dropbox_ops", + "SFTPClient", "sftp_instance", "register_sftp_ops", + "FTPClient", "ftp_instance", "register_ftp_ops", + "OneDriveClient", "onedrive_instance", "register_onedrive_ops", + "BoxClient", "box_instance", "register_box_ops", + "TCPActionServer", "start_autocontrol_socket_server", + "HTTPActionServer", "start_http_action_server", + "HTTPActionClient", "ProjectBuilder", + "scheduler", "schedule_add", "schedule_remove", "schedule_remove_all", "schedule_list", + "trigger_manager", "watch_start", "watch_stop", "watch_stop_all", "watch_list", + "notification_manager", "notify_send", + "launch_ui", ] mail_thunder_keys: list = [ diff --git a/pyproject.toml b/pyproject.toml index a6895a4..ecb133f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" [project] name = "pybreeze" -version = "1.0.19" +version = "1.0.21" authors = [ { name = "JE-Chen", email = "jechenmailman@gmail.com" }, ]