- Add tests/ directory to .gitignore - Document database connectivity with pyodbc and config - Add project structure and file organization guidelines - Update installation steps to use requirements.txt - Document new dependencies: pandas, openpyxl, pyodbc
184 lines
5.6 KiB
Markdown
184 lines
5.6 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
This is a Python automation project using Playwright to interact with a Chinese ERP system (YonBIP/用友). The scripts automate login, navigation, form filling, and data submission workflows in a nested iframe environment.
|
|
|
|
## Environment Setup
|
|
|
|
```bash
|
|
# Activate the virtual environment (Windows)
|
|
.venv\Scripts\activate
|
|
|
|
# Install all dependencies
|
|
pip install -r requirements.txt
|
|
|
|
# Install Playwright browsers
|
|
playwright install chromium
|
|
```
|
|
|
|
## Running Scripts
|
|
|
|
```bash
|
|
# Run the main test script
|
|
python tests/test_playwright.py
|
|
|
|
# Run the record script
|
|
python record.py
|
|
|
|
# Run database query test
|
|
python tests/test_db_query.py
|
|
```
|
|
|
|
## Key Dependencies
|
|
|
|
- **playwright==1.57.0**: Browser automation framework
|
|
- **pyodbc**: SQL Server database connectivity
|
|
- **pandas**: Data processing and Excel file handling
|
|
- **openpyxl**: Excel file operations
|
|
- Uses synchronous API (`playwright.sync_api`)
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
playwrite/
|
|
├── config/ # Configuration files (database, etc.)
|
|
├── db/ # Database connection components
|
|
├── data/ # Data files (excluded from git)
|
|
├── docs/ # Documentation (e.g., DEPENDENCIES.md)
|
|
├── tests/ # Test scripts (excluded from git)
|
|
├── requirements.txt # Python dependencies
|
|
├── .gitignore # Git ignore rules
|
|
└── CLAUDE.md # This file
|
|
```
|
|
|
|
## File Organization Rules
|
|
|
|
**IMPORTANT**: When creating test scripts, always place them in the `tests/` folder:
|
|
|
|
- Test scripts should be prefixed with `test_`
|
|
- All files in `tests/` are excluded from git tracking
|
|
- Examples: `tests/test_playwright.py`, `tests/test_db_query.py`
|
|
|
|
**Configuration Management**:
|
|
- Place configuration files in `config/` folder
|
|
- Database credentials and settings go in `config/database_config.py`
|
|
|
|
**Data Storage**:
|
|
- Use `data/` folder for temporary data files
|
|
- This folder is excluded from git tracking
|
|
|
|
## Architecture
|
|
|
|
### Nested Iframe Structure
|
|
|
|
The target application uses deeply nested iframes that require careful handling:
|
|
|
|
```
|
|
page (browser context)
|
|
└── #forwardFrame (main iframe)
|
|
└── #mainiframe (inner iframe, contains actual application UI)
|
|
```
|
|
|
|
**Critical Pattern**: When accessing nested iframes, always wait for the inner iframe to be visible before extracting its content frame:
|
|
|
|
```python
|
|
outer_frame = page.locator("#forwardFrame").content_frame
|
|
inner_frame_locator = outer_frame.locator("#mainiframe")
|
|
inner_frame_locator.wait_for(state="visible", timeout=15000)
|
|
inner_frame = inner_frame_locator.content_frame
|
|
```
|
|
|
|
### Loading State Management
|
|
|
|
The application uses loading overlays ("加载中") that must be detected and waited for:
|
|
|
|
```python
|
|
# Detect and wait for loading to complete
|
|
loading_locator = frame.locator("div").filter(has_text="加载中").nth(1)
|
|
try:
|
|
loading_locator.wait_for(state="visible", timeout=3000)
|
|
loading_locator.wait_for(state="hidden", timeout=0) # Infinite wait
|
|
except TimeoutError:
|
|
# Loading completed quickly or never appeared
|
|
pass
|
|
```
|
|
|
|
### Page Navigation Pattern
|
|
|
|
New windows/popups are handled using `expect_popup()`:
|
|
|
|
```python
|
|
with page.expect_popup() as popup_info:
|
|
some_button.click()
|
|
new_page = popup_info.value
|
|
```
|
|
|
|
### Database Connection
|
|
|
|
The project uses `pyodbc` to connect to SQL Server for data queries:
|
|
|
|
```python
|
|
from db.connection import get_connection
|
|
|
|
# Using context manager
|
|
with get_connection() as db:
|
|
results = db.execute_query("SELECT * FROM table")
|
|
# Connection automatically closed
|
|
|
|
# Using the query helper
|
|
from db.connection import query_production_orders
|
|
results = query_production_orders(['ID1', 'ID2', 'ID3'])
|
|
```
|
|
|
|
Database configuration is stored in `config/database_config.py`:
|
|
```python
|
|
SQL_SERVER_CONFIG = {
|
|
'driver': 'ODBC Driver 18 for SQL Server',
|
|
'server': '192.168.110.114',
|
|
'database': 'CompanyDB',
|
|
'username': 'peng',
|
|
'password': 'Cqbld123456.',
|
|
'TrustServerCertificate': 'yes'
|
|
}
|
|
```
|
|
|
|
## Common Utilities
|
|
|
|
### `get_input_by_label(frame, label_text)`
|
|
|
|
Locates input fields by their associated label text. Searches upward through parent containers to find the input:
|
|
|
|
```python
|
|
input_box = get_input_by_label(frame, "生产部门")
|
|
if input_box:
|
|
current_value = input_box.input_value()
|
|
input_box.fill("new value")
|
|
```
|
|
|
|
### `click_button_until_disappear(frame, button_name, max_attempts, max_duration)`
|
|
|
|
Continuously clicks a button until it disappears from the DOM. Includes logic to auto-fill missing data before each click.
|
|
|
|
## Development Notes
|
|
|
|
- **Browser launch**: `chromium.launch(headless=False)` for debugging
|
|
- **HTTPS errors**: Ignored with `ignore_https_errors=True` due to self-signed certificates on target system
|
|
- **Locators**: Uses role-based locators (`get_by_role()`) where possible, falling back to CSS selectors and text filtering
|
|
- **Text matching**: Uses regular expressions for matching text with patterns like `re.compile(r"^生产部门$")`
|
|
- **Date format**: "YYYY-MM-DD" (e.g., "2025-12-28")
|
|
- **Language**: Application is in Chinese; comments and print statements use Chinese for clarity
|
|
- **Debugging**: Uses `pdb.set_trace()` for interactive debugging sessions
|
|
|
|
## Target Application Details
|
|
|
|
- **URL**: `https://68.11.34.30:8082/` (internal network)
|
|
- **System**: YonBIP (用友) ERP system
|
|
- **Login**: Requires username and password; may show "force login" confirmation dialog
|
|
- **Key workflows**:
|
|
- "补货安排" (Replenishment Arrangement)
|
|
- "生产订单" (Production Orders)
|
|
- Batch data submission with "保存提交" (Save & Submit) button
|