docs: add complete login and existing stock data download workflow
- Add Mermaid sequence diagram covering login to download completion - Document 5 phases: Login (4 steps), App selection (2 steps), Query scheme (2 steps), Download execution (2 steps), Data waiting (1 step) - Include element loading wait mechanism with TypeScript implementation - Add HOVER trigger warning for row operation dropdown (emphasized by user) - Add complete outerHTML reference for all UI elements - Document forced login popup handling - Add element selector reference table
This commit is contained in:
390
docs/现存量数据下载流程.md
Normal file
390
docs/现存量数据下载流程.md
Normal file
@@ -0,0 +1,390 @@
|
|||||||
|
# 登录及现存量数据下载完整流程
|
||||||
|
|
||||||
|
本文档使用 Mermaid 流程图呈现从**登录系统**到**完成现存量数据下载**的全过程。
|
||||||
|
|
||||||
|
> **⚠️ 重要提示**
|
||||||
|
>
|
||||||
|
> 1. **每个操作前必须等待目标元素加载完成** —— 网页反应速度有限,不可假设点击后立即可以操作下一步
|
||||||
|
> 2. **下载步骤 9 只能用 HOVER 触发,点击无效** —— 用户特别强调 (4 个感叹号)
|
||||||
|
> 3. **条件分支以用户实际观察为准** —— 不推测原因,只呈现现象
|
||||||
|
> 4. **登录流程包含强制登录弹窗处理** —— 系统可能弹出"确定"确认框
|
||||||
|
|
||||||
|
## 流程总览
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant User as 用户
|
||||||
|
participant Page as 页面
|
||||||
|
participant System as 系统
|
||||||
|
participant HistoryPanel as 历史数据侧边栏
|
||||||
|
|
||||||
|
Note over User,HistoryPanel: 阶段 0: 登录系统
|
||||||
|
Page->>Page: 导航到登录 URL
|
||||||
|
Page->>Page: 等待#forwardFrame iframe 加载完成
|
||||||
|
|
||||||
|
User->>Page: 1. 填写用户名
|
||||||
|
Page->>Page: 等待密码框加载完成
|
||||||
|
User->>Page: 2. 填写密码
|
||||||
|
Page->>Page: 等待登录按钮加载完成
|
||||||
|
User->>Page: 3. 点击登录按钮
|
||||||
|
|
||||||
|
alt 出现强制登录确认框
|
||||||
|
Page->>Page: 弹出"确定"确认框
|
||||||
|
User->>Page: 4. 点击"确定"按钮
|
||||||
|
Note over User,HistoryPanel: 强制登录模式
|
||||||
|
else 无确认框
|
||||||
|
Note over User,HistoryPanel: 正常登录模式
|
||||||
|
end
|
||||||
|
|
||||||
|
Page->>Page: 等待登录完成
|
||||||
|
Page->>Page: 进入系统主页
|
||||||
|
|
||||||
|
Note over User,HistoryPanel: 阶段 1: 应用选择
|
||||||
|
Page->>Page: 等待应用菜单图标加载完成
|
||||||
|
User->>Page: 5. 点击应用菜单图标
|
||||||
|
Page->>Page: 展开应用列表
|
||||||
|
|
||||||
|
Page->>Page: 等待"现存量"应用项加载完成
|
||||||
|
User->>Page: 6. 点击"现存量"应用
|
||||||
|
Page->>Page: 打开新标签页
|
||||||
|
|
||||||
|
Note over User,HistoryPanel: 阶段 2: 查询方案选择
|
||||||
|
Page->>Page: 等待行操作下拉图标加载完成
|
||||||
|
User->>Page: 7. 点击行操作下拉图标
|
||||||
|
Page->>Page: 弹出查询方案列表
|
||||||
|
|
||||||
|
Page->>Page: 等待"现存量 - 总量"选项加载完成
|
||||||
|
User->>Page: 8. 点击"现存量 - 总量"
|
||||||
|
|
||||||
|
alt 出现"正在加载,请耐心等待"提示
|
||||||
|
Page->>Page: 显示全屏加载提示
|
||||||
|
Page->>Page: 等待加载完成
|
||||||
|
Page->>Page: 显示查询结果
|
||||||
|
else 页面无提示,仅短暂卡顿 (1-3 秒)
|
||||||
|
Page->>Page: 短暂卡顿
|
||||||
|
Page->>Page: 显示查询结果
|
||||||
|
end
|
||||||
|
|
||||||
|
Note over User,HistoryPanel: 阶段 3: 执行下载
|
||||||
|
Page->>Page: 等待查询结果数据加载完成
|
||||||
|
Page->>Page: 等待行操作下拉图标 (打印图标) 加载完成
|
||||||
|
|
||||||
|
rect rgb(255, 240, 200)
|
||||||
|
Note over User,Page: ⚠️ 只能使用 **HOVER**,点击无法触发!
|
||||||
|
User->>Page: 9. HOVER 触发行操作下拉图标
|
||||||
|
end
|
||||||
|
Page->>Page: 弹出操作菜单
|
||||||
|
|
||||||
|
Page->>Page: 等待"输出 xlsx 文件"选项加载完成
|
||||||
|
User->>Page: 10. 点击"输出 xlsx 文件"
|
||||||
|
|
||||||
|
alt 弹出确认对话框
|
||||||
|
Page->>Page: 显示确认对话框
|
||||||
|
Page->>Page: 记录点击"继续"的时间戳 T
|
||||||
|
User->>Page: 点击"继续"按钮
|
||||||
|
|
||||||
|
Note over User,HistoryPanel: 阶段 4: 等待数据准备
|
||||||
|
User->>HistoryPanel: 11. 点击"历史数据"图标
|
||||||
|
HistoryPanel->>HistoryPanel: 打开侧边栏
|
||||||
|
|
||||||
|
Page->>Page: 等待"实时分享"标签加载完成
|
||||||
|
User->>HistoryPanel: 点击"实时分享"标签
|
||||||
|
HistoryPanel->>HistoryPanel: 显示数据列表
|
||||||
|
|
||||||
|
loop 循环检查直到找到目标数据
|
||||||
|
HistoryPanel->>HistoryPanel: 获取所有记录的时间戳
|
||||||
|
HistoryPanel->>HistoryPanel: 检查:存在时间戳 > T 的记录?
|
||||||
|
alt 存在符合条件的记录
|
||||||
|
HistoryPanel->>HistoryPanel: 找到目标数据
|
||||||
|
else 不存在符合条件的记录
|
||||||
|
User->>HistoryPanel: 关闭侧边栏
|
||||||
|
Note over User,HistoryPanel: 等待片刻 (如 5 秒)
|
||||||
|
User->>HistoryPanel: 再次点击"历史数据"图标
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Page->>Page: 等待下载图标加载完成
|
||||||
|
User->>HistoryPanel: 点击下载图标
|
||||||
|
HistoryPanel->>User: 触发下载
|
||||||
|
else 无对话框,直接下载
|
||||||
|
Page->>User: 直接触发下载
|
||||||
|
end
|
||||||
|
|
||||||
|
Note over User,HistoryPanel: ✅ 下载完成
|
||||||
|
```
|
||||||
|
|
||||||
|
## 详细步骤说明
|
||||||
|
|
||||||
|
### 阶段 0: 登录系统
|
||||||
|
|
||||||
|
| 步骤 | 操作 | 前置条件 | 元素选择器 / OuterHTML |
|
||||||
|
|------|------|----------|----------------------|
|
||||||
|
| 1 | 填写用户名 | 登录页面 #forwardFrame iframe 已加载完成 | `main_frame.get_by_role("textbox", name="用户名").fill(username)` |
|
||||||
|
| 2 | 填写密码 | 用户名已填写完成 | `main_frame.get_by_role("textbox", name="密码").fill(password)` |
|
||||||
|
| 3 | 点击登录按钮 | 密码已填写完成 | `main_frame.get_by_role("button", name="登录").click()` |
|
||||||
|
| 4 | 处理强制登录确认框 (如出现) | 登录按钮已点击 | `main_frame.get_by_role("button", name="确定").click()` |
|
||||||
|
|
||||||
|
**登录流程说明:**
|
||||||
|
|
||||||
|
1. **导航到登录页面** - 使用完整 URL:
|
||||||
|
```python
|
||||||
|
url = f"{base_url.rstrip('/')}/yonbip/resources/uap/rbac/login/main/index.html"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **定位 iframe** - 所有登录表单元素都在 `#forwardFrame` iframe 内:
|
||||||
|
```python
|
||||||
|
main_frame = page.locator("#forwardFrame").content_frame
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **填写凭据** - 使用 Playwright 的 role 定位器:
|
||||||
|
```python
|
||||||
|
main_frame.get_by_role("textbox", name="用户名").fill(username)
|
||||||
|
main_frame.get_by_role("textbox", name="密码").fill(password)
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **点击登录** - 登录按钮:
|
||||||
|
```python
|
||||||
|
main_frame.get_by_role("button", name="登录").click()
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **处理强制登录弹窗** - 系统可能弹出确认框:
|
||||||
|
```python
|
||||||
|
confirm_btn = main_frame.get_by_role("button", name="确定")
|
||||||
|
if confirm_btn.count() > 0:
|
||||||
|
confirm_btn.click() # 强制登录模式
|
||||||
|
else:
|
||||||
|
pass # 正常登录模式
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **等待登录完成** - 登录后进入系统主页,准备进行下一步操作
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 阶段 1: 应用选择
|
||||||
|
|
||||||
|
| 步骤 | 操作 | 前置条件 | 元素 OuterHTML (完整) |
|
||||||
|
|------|------|----------|----------------------|
|
||||||
|
| 5 | 点击应用菜单图标 | 登录后的主页已加载完成 | `<div class="nc-workbench-icon" data-step="1" data-intro=" <img src=images/novice-guide-allapps.gif alt="" class='novice-guide-allapps' /> <p>应用菜单</p> <div class='span-box'> <span>展示全部有权限的应用。在"我的应用"中,可查看"我的收藏"和"最近访问"的应用。</span> </div> <i class='iconfont icon-guanbi2 guide-close' onclick="handleWorkbenchIntro('close')"></i> "><i style="background-image: url("images/logo2.svg");"></i></div>` |
|
||||||
|
| 6 | 点击"现存量"应用 | 应用列表已展开完成 | `<div class="item-app" open-type="tab" grp-index="0" item-index="5" title="现存量" style="min-width: 255px;">现存量<div class="icon-content"><i class="iconfont icon-xinyeqiandakai app-open" grp-index="0" item-index="5" open-type="newtab" date-for-wui-tooltip="wui-tooltip-8makk4g2uj"></i><i class="iconfont icon-shoucangdianliang" date-for-wui-tooltip="wui-tooltip-79heoa4zzh" style="color: rgb(240, 158, 68); font-size: 16px; visibility: visible;"></i></div></div>` |
|
||||||
|
|
||||||
|
### 阶段 2: 查询方案选择
|
||||||
|
|
||||||
|
| 步骤 | 操作 | 前置条件 | 元素 OuterHTML (完整) |
|
||||||
|
|------|------|----------|----------------------|
|
||||||
|
| 7 | 点击行操作下拉图标 | 现存量页面已加载完成 | `<i class="iconfont icon-hangcaozuoxiala1"></i>` |
|
||||||
|
| 8 | 点击"现存量 - 总量"方案 | 查询方案列表已弹出完成 | (列表项,通过文本"现存量 - 总量"定位) |
|
||||||
|
|
||||||
|
**步骤 8 后的两种可能情况:**
|
||||||
|
|
||||||
|
| 情况 | 现象 | OuterHTML | 处理 |
|
||||||
|
|------|------|-----------|------|
|
||||||
|
| 可能性 1 | 出现"正在加载,请耐心等待"全屏提示 | `<div class="wui-spin-backdrop wui-spin-full-screen base-loading-back-drop" style="z-index: 1900;"><div class="wui-spin-default-container "><div class="wui-spin wui-spin-default wui-spin-show-text base-loading base-loading-spin-show"><div class="wui-spin-spin wui-spin-dot wui-spin-dot-spin"><i></i><i></i><i></i><i></i></div></div><div class="wui-spin-desc">加载中...</div></div></div>` | 等待加载完成,直到该元素消失 |
|
||||||
|
| 可能性 2 | 页面无提示,仅短暂卡顿 (1-3 秒) | 无额外元素出现 | 等待 1-3 秒即可 |
|
||||||
|
|
||||||
|
### 阶段 3: 执行下载
|
||||||
|
|
||||||
|
| 步骤 | 操作 | 前置条件 | 元素 OuterHTML (完整) |
|
||||||
|
|------|------|----------|----------------------|
|
||||||
|
| 9 | **HOVER** 触发行操作下拉图标 | 查询结果数据已显示完成 | `<span class="wui-button-text-wrap"><i class="arrow iconfont icon-hangcaozuoxiala1 nc-button-area-print-icon "></i></span>` |
|
||||||
|
| 10 | 点击"输出 xlsx 文件" | 操作菜单已弹出完成 | `<li class="wui-menu-item wui-menu-item-only-child dropdown-btn-item" role="menuitem" tabindex="-1" btn-code="xlsx" date-for-wui-tooltip="wui-tooltip-cj1jzq1434" aria-disabled="false" data-menu-id="rc-menu-uuid-36646-2-xlsx"><span date-for-wui-tooltip="wui-tooltip-vvedhdkxwj"><div class="dropdown-btn-item-box"><div class="btn-item-left-wrapper"><div class="btn-item-left" btn-code="xlsx">输出 xlsx 文件</div></div></div></span></li>` |
|
||||||
|
|
||||||
|
> **⚠️ 步骤 9 特别警告**
|
||||||
|
>
|
||||||
|
> - **必须使用 HOVER 动作,点击无法正确触发!**
|
||||||
|
> - 用户用 4 个感叹号强调此点
|
||||||
|
> - 实现代码示例:
|
||||||
|
> ```typescript
|
||||||
|
> // 正确方式
|
||||||
|
> await dropdownTrigger.hover();
|
||||||
|
> await page.waitForTimeout(1000); // 等待菜单展开
|
||||||
|
>
|
||||||
|
> // ❌ 错误方式:不要使用 click()
|
||||||
|
> // await dropdownTrigger.click();
|
||||||
|
> ```
|
||||||
|
|
||||||
|
**步骤 10 后的两种可能情况:**
|
||||||
|
|
||||||
|
| 情况 | 现象 | OuterHTML | 处理 |
|
||||||
|
|------|------|-----------|------|
|
||||||
|
| 可能性 1 | 弹出确认对话框 | `<div class="wui-modal-body">当前数据较多,系统在处理完成后会发送通知消息,是否继续?</div>`<br/>`<button type="button" class="wui-button sure-button nc-button-wrapper button-primary " tabindex="-1"><span class="wui-button-text-wrap">继续</span></button>` | 点击"继续"按钮,然后进入阶段 4 |
|
||||||
|
| 可能性 2 | 无对话框 | 无额外元素出现 | 直接触发下载,流程结束 |
|
||||||
|
|
||||||
|
### 阶段 4: 等待数据准备 (仅当步骤 10 弹出确认对话框时)
|
||||||
|
|
||||||
|
**确认对话框元素:**
|
||||||
|
```html
|
||||||
|
<div class="wui-modal-resizbox modal-content-resizeWrap react-draggable">
|
||||||
|
<div class="wui-modal-content">
|
||||||
|
<div class="wui-modal-body">当前数据较多,系统在处理完成后会发送通知消息,是否继续?</div>
|
||||||
|
<div class="wui-modal-footer">
|
||||||
|
<button class="wui-button sure-button">继续</button>
|
||||||
|
<button class="wui-button cancel-button">取消</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
**数据等待子流程:**
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
A[点击继续按钮] --> B[记录点击时间 T<br/>格式:YYYY-MM-DD HH:mm:ss]
|
||||||
|
B --> C[点击历史数据图标]
|
||||||
|
C --> D[侧边栏打开]
|
||||||
|
D --> E[点击实时分享标签]
|
||||||
|
E --> F[获取数据列表]
|
||||||
|
F --> G{存在时间戳 > T 的记录?}
|
||||||
|
G -->|是 | H[找到目标数据<br/>选择最新的一条]
|
||||||
|
G -->|否 | I[关闭侧边栏]
|
||||||
|
I --> J["等待片刻 (建议 5 秒)"]
|
||||||
|
J --> C
|
||||||
|
|
||||||
|
H --> K[点击下载图标]
|
||||||
|
K --> L[下载完成]
|
||||||
|
```
|
||||||
|
|
||||||
|
**历史数据元素结构 (完整 OuterHTML):**
|
||||||
|
```html
|
||||||
|
<li class="history nc-theme-xrow-bgc">
|
||||||
|
<p class="title sidebox-title-class" date-for-wui-tooltip="wui-tooltip-d2n8imkyvl">现存量</p>
|
||||||
|
<span class="ts sidebox-ts-class">2026-04-09 14:16:03</span>
|
||||||
|
<br>
|
||||||
|
<span class="ts sidebox-ts-class">发送人:彭强强</span>
|
||||||
|
<i class="read-icon not-read">未读</i>
|
||||||
|
<span class="icon iconfont icon-xiazai1" date-for-wui-tooltip="wui-tooltip-h6v3886qti"></span>
|
||||||
|
</li>
|
||||||
|
```
|
||||||
|
|
||||||
|
**时间判断逻辑:**
|
||||||
|
1. 记录点击"继续"按钮的时间戳 `T` (格式:`YYYY-MM-DD HH:mm:ss`)
|
||||||
|
2. 获取历史数据列表中所有记录的时间戳 (从 `<span class="ts sidebox-ts-class">` 提取)
|
||||||
|
3. 遍历检查:`record_timestamp > T`
|
||||||
|
4. 如果存在符合条件的记录 → 选择**最新的一条** (第一条通常是最新的)
|
||||||
|
5. 如果不存在 → 关闭侧边栏,等待 5 秒后重试
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 元素加载等待机制
|
||||||
|
|
||||||
|
**这是用户特别强调的核心机制** —— 每次操作前必须确认目标元素已加载完成。
|
||||||
|
|
||||||
|
### 等待函数实现
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
/**
|
||||||
|
* 等待元素加载完成
|
||||||
|
* @param locator - Playwright locator
|
||||||
|
* @param options - 配置选项
|
||||||
|
* - timeout: 超时时间 (毫秒),默认 30000
|
||||||
|
* - state: 等待状态 ('visible' | 'attached' | 'hidden'),默认 'visible'
|
||||||
|
* - extraDelay: 额外等待时间 (毫秒),默认 500,确保元素完全可交互
|
||||||
|
*/
|
||||||
|
async function waitForElement(locator: Locator, options: {
|
||||||
|
timeout?: number;
|
||||||
|
state?: 'visible' | 'attached' | 'hidden';
|
||||||
|
extraDelay?: number;
|
||||||
|
} = {}): Promise<void> {
|
||||||
|
const { timeout = 30000, state = 'visible', extraDelay = 500 } = options;
|
||||||
|
|
||||||
|
// 等待元素达到指定状态
|
||||||
|
await locator.waitFor({ state, timeout });
|
||||||
|
|
||||||
|
// 额外等待,确保元素完全可交互
|
||||||
|
if (extraDelay > 0) {
|
||||||
|
await page.waitForTimeout(extraDelay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 在主流程中的应用
|
||||||
|
|
||||||
|
每个步骤的标准操作模式:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 登录阶段:填写用户名
|
||||||
|
const usernameInput = main_frame.getByRole('textbox', { name: '用户名' });
|
||||||
|
await waitForElement(usernameInput);
|
||||||
|
await usernameInput.fill(username);
|
||||||
|
|
||||||
|
// 登录阶段:填写密码
|
||||||
|
const passwordInput = main_frame.getByRole('textbox', { name: '密码' });
|
||||||
|
await waitForElement(passwordInput);
|
||||||
|
await passwordInput.fill(password);
|
||||||
|
|
||||||
|
// 登录阶段:点击登录按钮
|
||||||
|
const loginButton = main_frame.getByRole('button', { name: '登录' });
|
||||||
|
await waitForElement(loginButton);
|
||||||
|
await loginButton.click();
|
||||||
|
|
||||||
|
// 登录阶段:处理强制登录确认框 (如出现)
|
||||||
|
const confirmButton = main_frame.getByRole('button', { name: '确定' });
|
||||||
|
if (await confirmButton.count() > 0) {
|
||||||
|
await confirmButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 步骤 5: 点击应用菜单
|
||||||
|
const menuIcon = page.locator('.nc-workbench-icon');
|
||||||
|
await waitForElement(menuIcon);
|
||||||
|
await menuIcon.click();
|
||||||
|
|
||||||
|
// 步骤 6: 点击"现存量"应用
|
||||||
|
const currentItem = page.locator('.item-app[title="现存量"]');
|
||||||
|
await waitForElement(currentItem);
|
||||||
|
await currentItem.click();
|
||||||
|
|
||||||
|
// 步骤 9: HOVER 触发 (特殊)
|
||||||
|
const dropdownTrigger = page.locator('span.wui-button-text-wrap i.icon-hangcaozuoxiala1.nc-button-area-print-icon');
|
||||||
|
await waitForElement(dropdownTrigger);
|
||||||
|
await dropdownTrigger.hover(); // ⚠️ 必须 HOVER,不能 click
|
||||||
|
await page.waitForTimeout(1000); // 等待菜单展开
|
||||||
|
|
||||||
|
// 步骤 8 后的加载等待
|
||||||
|
const loadingBackdrop = page.locator('.wui-spin-backdrop.wui-spin-full-screen');
|
||||||
|
if (await loadingBackdrop.isVisible()) {
|
||||||
|
await loadingBackdrop.waitFor({ state: 'hidden', timeout: 60000 });
|
||||||
|
} else {
|
||||||
|
await page.waitForTimeout(3000); // 无提示时等待 1-3 秒
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 元素选择器参考表
|
||||||
|
|
||||||
|
### 主流程元素
|
||||||
|
|
||||||
|
| 阶段 | 步骤 | 元素 | 选择器 (精简) | 完整 OuterHTML 参考 |
|
||||||
|
|------|------|------|--------------|-------------------|
|
||||||
|
| 0 (登录) | 1 | 用户名输入框 | `getByRole("textbox", name="用户名")` | 见阶段 0 表格 |
|
||||||
|
| 0 (登录) | 2 | 密码输入框 | `getByRole("textbox", name="密码")` | 见阶段 0 表格 |
|
||||||
|
| 0 (登录) | 3 | 登录按钮 | `getByRole("button", name="登录")` | 见阶段 0 表格 |
|
||||||
|
| 0 (登录) | 4 | 强制登录确认按钮 | `getByRole("button", name="确定")` | 见阶段 0 表格 |
|
||||||
|
| 1 | 5 | 应用菜单图标 | `.nc-workbench-icon` | 见阶段 1 表格 |
|
||||||
|
| 1 | 6 | "现存量"应用 | `.item-app[title="现存量"]` | 见阶段 1 表格 |
|
||||||
|
| 2 | 7 | 查询方案下拉 | `i.icon-hangcaozuoxiala1` | 见阶段 2 表格 |
|
||||||
|
| 2 | 8 | "现存量 - 总量" | 文本定位 | 见阶段 2 表格 |
|
||||||
|
| 3 | 9 | 行操作下拉 (HOVER) | `span.wui-button-text-wrap i.icon-hangcaozuoxiala1.nc-button-area-print-icon` | 见阶段 3 表格 |
|
||||||
|
| 3 | 10 | "输出 xlsx 文件" | `li.wui-menu-item[btn-code="xlsx"]` | 见阶段 3 表格 |
|
||||||
|
| 4 | 11 | "历史数据"图标 | `button.nc-button-wrapper i.icon-fenxianglishi` | - |
|
||||||
|
| 4 | 11 | "实时分享"标签 | `div[role="tab"][nodekey="current"]` | - |
|
||||||
|
| 4 | 11 | 下载图标 | `span.icon-xiazai1` | 见阶段 4 历史数据元素 |
|
||||||
|
|
||||||
|
### 弹窗元素
|
||||||
|
|
||||||
|
| 元素 | 选择器 | 用途 |
|
||||||
|
|------|--------|------|
|
||||||
|
| 加载提示 | `.wui-spin-backdrop.wui-spin-full-screen` | 等待加载完成 |
|
||||||
|
| 确认对话框 `.wui-modal-body` (含文本判断) | 识别确认对话框 |
|
||||||
|
| "继续"按钮 | `button.sure-button` | 确认继续 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 实现注意事项
|
||||||
|
|
||||||
|
1. **时间戳格式必须一致** —— 点击"继续"按钮记录的时间 T 必须与页面显示的时间戳格式相同 (`YYYY-MM-DD HH:mm:ss`)
|
||||||
|
|
||||||
|
2. **循环等待需设置最大次数** —— 避免无限循环,建议设置最大重试次数 (如 10 次)
|
||||||
|
|
||||||
|
3. **侧边栏关闭后需等待** —— 关闭侧边栏后至少等待 5 秒再重新打开,给系统处理数据的时间
|
||||||
|
|
||||||
|
4. **HOVER 后需等待菜单展开** —— HOVER 动作后至少等待 1 秒再执行下一步点击
|
||||||
Reference in New Issue
Block a user