|
|
@@ -64,6 +64,8 @@ export class EnterpriseMiniPage {
|
|
|
|
|
|
// 主页选择器(登录后可用)
|
|
|
this.userInfo = page.getByTestId('mini-user-info');
|
|
|
+ // 设置按钮
|
|
|
+ this.settingsButton = page.getByText('设置').nth(1);
|
|
|
// 退出登录按钮 - 使用 getByText 而非 getByRole
|
|
|
this.logoutButton = page.getByText('退出登录');
|
|
|
}
|
|
|
@@ -134,28 +136,31 @@ export class EnterpriseMiniPage {
|
|
|
* 填写密码
|
|
|
* @param password 密码(6-20位)
|
|
|
*
|
|
|
- * 注意:使用 click + type 方法触发自然的用户输入事件
|
|
|
- * Taro Input 组件需要完整的事件流才能正确更新 react-hook-form 状态
|
|
|
+ * 注意:taro-input-core 是 Taro 框架的自定义组件,不是标准 HTML 元素
|
|
|
+ * 需要使用 evaluate() 直接操作 DOM 元素来设置值和触发事件
|
|
|
*/
|
|
|
async fillPassword(password: string): Promise<void> {
|
|
|
await this.removeDevOverlays();
|
|
|
await this.passwordInput.click();
|
|
|
await this.page.waitForTimeout(100);
|
|
|
- // 使用 fill 方法一次性填充
|
|
|
- await this.passwordInput.fill(password);
|
|
|
+
|
|
|
+ // taro-input-core 不是标准 input 元素,使用 JS 直接设置值并触发事件
|
|
|
+ await this.passwordInput.evaluate((el, val) => {
|
|
|
+ // 尝试找到内部的真实 input 元素
|
|
|
+ const nativeInput = el.querySelector('input') || el;
|
|
|
+ if (nativeInput instanceof HTMLInputElement) {
|
|
|
+ nativeInput.value = val;
|
|
|
+ nativeInput.dispatchEvent(new Event('input', { bubbles: true }));
|
|
|
+ nativeInput.dispatchEvent(new Event('change', { bubbles: true }));
|
|
|
+ } else {
|
|
|
+ // 如果找不到 input 元素,设置 value 属性
|
|
|
+ (el as any).value = val;
|
|
|
+ el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
|
+ el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
|
+ }
|
|
|
+ }, password);
|
|
|
+
|
|
|
await this.page.waitForTimeout(300);
|
|
|
- // 验证输入值
|
|
|
- const actualValue = await this.passwordInput.inputValue();
|
|
|
- if (actualValue !== password) {
|
|
|
- // 使用 JS 直接设置
|
|
|
- await this.passwordInput.evaluate((el, val) => {
|
|
|
- const input = el as HTMLInputElement;
|
|
|
- input.value = val;
|
|
|
- input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
|
- input.dispatchEvent(new Event('change', { bubbles: true }));
|
|
|
- }, password);
|
|
|
- await this.page.waitForTimeout(200);
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -362,12 +367,53 @@ export class EnterpriseMiniPage {
|
|
|
|
|
|
/**
|
|
|
* 退出登录
|
|
|
+ *
|
|
|
+ * 注意:企业小程序的退出登录按钮在设置页面中,需要先点击设置按钮
|
|
|
*/
|
|
|
async logout(): Promise<void> {
|
|
|
- // 点击退出登录按钮
|
|
|
- await this.logoutButton.click();
|
|
|
- // 等待页面加载完成
|
|
|
- await this.page.waitForLoadState('domcontentloaded');
|
|
|
+ // 先点击设置按钮进入设置页面
|
|
|
+ await this.settingsButton.click();
|
|
|
+ await this.page.waitForTimeout(500);
|
|
|
+
|
|
|
+ // 滚动到页面底部,确保退出登录按钮可见
|
|
|
+ await this.page.evaluate(() => {
|
|
|
+ window.scrollTo(0, document.body.scrollHeight);
|
|
|
+ });
|
|
|
+ await this.page.waitForTimeout(300);
|
|
|
+
|
|
|
+ // 点击退出登录按钮(使用 JS 直接点击来绕过 Taro 组件的事件处理)
|
|
|
+ await this.logoutButton.evaluate((el) => {
|
|
|
+ // 查找包含该文本的可点击元素
|
|
|
+ const button = el.closest('button') || el.closest('[role="button"]') || el;
|
|
|
+ (button as HTMLElement).click();
|
|
|
+ });
|
|
|
+
|
|
|
+ // 等待确认对话框出现
|
|
|
+ await this.page.waitForTimeout(1500);
|
|
|
+
|
|
|
+ // 处理确认对话框 - Taro.showModal 会显示一个确认对话框
|
|
|
+ // 使用更具体的选择器,因为对话框有两个按钮(取消/确定)
|
|
|
+ const _confirmButton = this.page.locator('.taro-modal__footer').getByText('确定').first();
|
|
|
+
|
|
|
+ // 尝试使用 JS 直接点击确定按钮
|
|
|
+ const dialogClicked = await this.page.evaluate(() => {
|
|
|
+ // 查找所有"确定"文本的元素
|
|
|
+ const buttons = Array.from(document.querySelectorAll('*'));
|
|
|
+ const confirmBtn = buttons.find(el => el.textContent === '确定' && el.textContent?.trim() === '确定');
|
|
|
+ if (confirmBtn) {
|
|
|
+ (confirmBtn as HTMLElement).click();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!dialogClicked) {
|
|
|
+ // 如果 JS 点击失败,尝试使用 Playwright 点击
|
|
|
+ await this.page.getByText('确定').click({ force: true });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 等待退出登录完成并跳转到登录页面
|
|
|
+ await this.page.waitForTimeout(3000);
|
|
|
}
|
|
|
|
|
|
/**
|