优化文件路径
This commit is contained in:
parent
6b263fc83f
commit
6e36aa1cd3
@ -14,18 +14,12 @@ test('隆基登录', async ({page}) => {
|
|||||||
// 2. 导航到登录页面
|
// 2. 导航到登录页面
|
||||||
await loginPage.navigateToLoginPage();
|
await loginPage.navigateToLoginPage();
|
||||||
|
|
||||||
// 3. 等待页面加载完成
|
|
||||||
await page.waitForLoadState('networkidle');
|
|
||||||
|
|
||||||
// 4. 点击登录按钮 - 使用页面对象模型
|
// 4. 点击登录按钮 - 使用页面对象模型
|
||||||
const clickSuccess = await loginPage.clickLoginButton();
|
const clickSuccess = await loginPage.clickLoginButton();
|
||||||
|
|
||||||
// 5. 验证点击是否成功
|
// 5. 验证点击是否成功
|
||||||
expect(clickSuccess, '验证是否登录成功').toBeTruthy();
|
expect(clickSuccess, '验证是否登录成功').toBeTruthy();
|
||||||
|
|
||||||
let loginSuccess = await loginPage.isLoginSuccessful();
|
|
||||||
console.log(`登录状态: ${loginSuccess ? '成功' : '失败'}`);
|
|
||||||
|
|
||||||
// 10. 检查菜单数据文件是否存在
|
// 10. 检查菜单数据文件是否存在
|
||||||
let menuItems = await mainPage.checkAndLoadMenuItems();
|
let menuItems = await mainPage.checkAndLoadMenuItems();
|
||||||
|
|
||||||
|
|||||||
@ -56,13 +56,16 @@ class BasePage {
|
|||||||
*/
|
*/
|
||||||
initializeConfig() {
|
initializeConfig() {
|
||||||
this.config = {
|
this.config = {
|
||||||
timeout: 30000, // 默认超时时间
|
timeout: {
|
||||||
|
page: 30000,
|
||||||
|
element: 30000,
|
||||||
|
navigate: 30000
|
||||||
|
},
|
||||||
pageLoad: {
|
pageLoad: {
|
||||||
maxRetries: 30,
|
maxRetries: 30,
|
||||||
retryInterval: 500,
|
retryInterval: 500,
|
||||||
stabilityDelay: 1000
|
stabilityDelay: 1000
|
||||||
},
|
}
|
||||||
menuTimeout: parseInt(process.env.MENU_TIME_OUT || '30000', 10)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +76,7 @@ class BasePage {
|
|||||||
async navigate(url) {
|
async navigate(url) {
|
||||||
await this.page.goto(url, {
|
await this.page.goto(url, {
|
||||||
waitUntil: 'networkidle',
|
waitUntil: 'networkidle',
|
||||||
timeout: 30000
|
timeout: this.config.timeout.navigate
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,13 +90,11 @@ class BasePage {
|
|||||||
*/
|
*/
|
||||||
async waitForElement(selector, options = {}) {
|
async waitForElement(selector, options = {}) {
|
||||||
try {
|
try {
|
||||||
const element = options.firstOnly ?
|
const element = options.firstOnly ? this.page.locator(selector).first() : this.page.locator(selector);
|
||||||
this.page.locator(selector).first() :
|
|
||||||
this.page.locator(selector);
|
|
||||||
|
|
||||||
await element.waitFor({
|
await element.waitFor({
|
||||||
state: 'visible',
|
state: 'visible',
|
||||||
timeout: options.timeout || this.config.timeout
|
timeout: this.config.timeout.element
|
||||||
});
|
});
|
||||||
|
|
||||||
return options.returnBoolean ? true : element;
|
return options.returnBoolean ? true : element;
|
||||||
@ -110,7 +111,7 @@ class BasePage {
|
|||||||
* @param {string} selector 元素选择器
|
* @param {string} selector 元素选择器
|
||||||
* @param {Object} options 选项
|
* @param {Object} options 选项
|
||||||
*/
|
*/
|
||||||
async click(selector, options = {}) {
|
async clickBySelector(selector, options = {}) {
|
||||||
const element = await this.waitForElement(selector, options);
|
const element = await this.waitForElement(selector, options);
|
||||||
await element.click(options);
|
await element.click(options);
|
||||||
}
|
}
|
||||||
@ -120,7 +121,7 @@ class BasePage {
|
|||||||
* @param {Object} element Playwright元素对象
|
* @param {Object} element Playwright元素对象
|
||||||
* @returns {Promise<boolean>} 是否点击成功
|
* @returns {Promise<boolean>} 是否点击成功
|
||||||
*/
|
*/
|
||||||
async safeClick(element) {
|
async clickByElement(element) {
|
||||||
try {
|
try {
|
||||||
await element.click();
|
await element.click();
|
||||||
return true;
|
return true;
|
||||||
@ -135,7 +136,7 @@ class BasePage {
|
|||||||
* @param {string} selector 要点击的元素选择器
|
* @param {string} selector 要点击的元素选择器
|
||||||
* @returns {Promise<boolean>} 操作是否成功
|
* @returns {Promise<boolean>} 操作是否成功
|
||||||
*/
|
*/
|
||||||
async clickAndWaitForLoad(selector) {
|
async clickBySelectorAndWaitForLoad(selector) {
|
||||||
try {
|
try {
|
||||||
const element = await this.waitForElement(selector);
|
const element = await this.waitForElement(selector);
|
||||||
await element.click();
|
await element.click();
|
||||||
@ -147,9 +148,9 @@ class BasePage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async safeClickAndWaitForLoad(element) {
|
async clickByElementAndWaitForLoad(element) {
|
||||||
try {
|
try {
|
||||||
await this.click(element);
|
await this.clickBySelector(element);
|
||||||
await this.waitForPageLoad();
|
await this.waitForPageLoad();
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -174,7 +175,7 @@ class BasePage {
|
|||||||
*/
|
*/
|
||||||
async waitForPageLoad() {
|
async waitForPageLoad() {
|
||||||
await this.page.waitForLoadState('networkidle', {
|
await this.page.waitForLoadState('networkidle', {
|
||||||
timeout: 30000
|
timeout: this.config.timeout.page
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +233,7 @@ class BasePage {
|
|||||||
for (const selector of errorSelectors) {
|
for (const selector of errorSelectors) {
|
||||||
const elements = await this.page.locator(selector).all();
|
const elements = await this.page.locator(selector).all();
|
||||||
if (elements.length > 0) {
|
if (elements.length > 0) {
|
||||||
const errorText = await this.getElementText(elements[0]);
|
const errorText = await this.getTextByElement(elements[0]);
|
||||||
console.error(`页面加载出现错误: ${pageName}, 错误信息: ${errorText}`);
|
console.error(`页面加载出现错误: ${pageName}, 错误信息: ${errorText}`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -274,7 +275,7 @@ class BasePage {
|
|||||||
* @param {Object} element Playwright元素对象
|
* @param {Object} element Playwright元素对象
|
||||||
* @returns {Promise<string>} 元素文本
|
* @returns {Promise<string>} 元素文本
|
||||||
*/
|
*/
|
||||||
async getElementText(element) {
|
async getTextByElement(element) {
|
||||||
try {
|
try {
|
||||||
const text = await element.textContent();
|
const text = await element.textContent();
|
||||||
return text.trim();
|
return text.trim();
|
||||||
|
|||||||
@ -53,6 +53,7 @@ class LongiLoginPage extends BasePage {
|
|||||||
async navigateToLoginPage() {
|
async navigateToLoginPage() {
|
||||||
console.log('当前使用的 BASE_URL:', process.env.BASE_URL);
|
console.log('当前使用的 BASE_URL:', process.env.BASE_URL);
|
||||||
await this.navigate(process.env.BASE_URL);
|
await this.navigate(process.env.BASE_URL);
|
||||||
|
await this.waitForPageLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,17 +62,17 @@ class LongiLoginPage extends BasePage {
|
|||||||
*/
|
*/
|
||||||
async clickLoginButton() {
|
async clickLoginButton() {
|
||||||
try {
|
try {
|
||||||
await this.clickAndWaitForLoad(this.selectors.loginButton)
|
await this.clickBySelectorAndWaitForLoad(this.selectors.loginButton)
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('第一种方法失败,尝试备用方法...');
|
console.log('第一种方法失败,尝试备用方法...');
|
||||||
try {
|
try {
|
||||||
await this.clickAndWaitForLoad(this.selectors.loginButtonByText)
|
await this.clickBySelectorAndWaitForLoad(this.selectors.loginButtonByText)
|
||||||
return true;
|
return true;
|
||||||
} catch (secondError) {
|
} catch (secondError) {
|
||||||
console.log('第二种方法也失败,尝试第三种方法...');
|
console.log('第二种方法也失败,尝试第三种方法...');
|
||||||
try {
|
try {
|
||||||
await this.safeClickAndWaitForLoad(await this.page.locator(this.selectors.loginButtonFirst).first());
|
await this.clickByElementAndWaitForLoad(await this.page.locator(this.selectors.loginButtonFirst).first());
|
||||||
return true;
|
return true;
|
||||||
} catch (thirdError) {
|
} catch (thirdError) {
|
||||||
console.error('所有方法都失败,无法点击登录按钮', thirdError);
|
console.error('所有方法都失败,无法点击登录按钮', thirdError);
|
||||||
@ -87,8 +88,7 @@ class LongiLoginPage extends BasePage {
|
|||||||
*/
|
*/
|
||||||
async isLoginSuccessful() {
|
async isLoginSuccessful() {
|
||||||
// 登录成功后通常会重定向到其他页面
|
// 登录成功后通常会重定向到其他页面
|
||||||
const currentUrl = await this.getCurrentUrl();
|
return (await this.getCurrentUrl()).includes('/dashboard');
|
||||||
return currentUrl.includes('/dashboard');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -49,7 +49,9 @@ class LongiMainPage extends BasePage {
|
|||||||
|
|
||||||
// 添加或覆盖特定于 LongiMainPage 的配置
|
// 添加或覆盖特定于 LongiMainPage 的配置
|
||||||
Object.assign(this.config, {
|
Object.assign(this.config, {
|
||||||
menuTimeout: parseInt(process.env.MENU_TIME_OUT || '30000', 10)
|
timeout: {
|
||||||
|
menuTimeout: parseInt(process.env.MENU_TIME_OUT || '30000', 10)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +236,7 @@ class LongiMainPage extends BasePage {
|
|||||||
* @returns {string} 菜单路径
|
* @returns {string} 菜单路径
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async getMenuPath(menuInfo, parentMenu = null) {
|
getMenuPath(menuInfo, parentMenu = null) {
|
||||||
return parentMenu ? `${parentMenu.text} > ${menuInfo.text}` : menuInfo.text;
|
return parentMenu ? `${parentMenu.text} > ${menuInfo.text}` : menuInfo.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,10 +406,10 @@ class LongiMainPage extends BasePage {
|
|||||||
* @param {Object} parentMenu 父级菜单(可选)
|
* @param {Object} parentMenu 父级菜单(可选)
|
||||||
*/
|
*/
|
||||||
async handleMenuClick(menuInfo, parentMenu = null) {
|
async handleMenuClick(menuInfo, parentMenu = null) {
|
||||||
const menuPath = this.getMenuPath(menuInfo, parentMenu);
|
const menuPath = await this.getMenuPath(menuInfo, parentMenu);
|
||||||
console.log(`点击菜单: ${menuPath}`);
|
console.log(`点击菜单: ${menuPath}`);
|
||||||
|
|
||||||
if (!await this.safeClick(menuInfo.element)) {
|
if (!await this.clickByElement(menuInfo.element)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +478,7 @@ class LongiMainPage extends BasePage {
|
|||||||
async getTabInfos(tabs) {
|
async getTabInfos(tabs) {
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
tabs.map(async element => ({
|
tabs.map(async element => ({
|
||||||
text: await this.getElementText(element),
|
text: await this.getTextByElement(element),
|
||||||
isActive: await element.evaluate(el => el.classList.contains('is-active')),
|
isActive: await element.evaluate(el => el.classList.contains('is-active')),
|
||||||
element: element
|
element: element
|
||||||
}))
|
}))
|
||||||
@ -495,7 +497,7 @@ class LongiMainPage extends BasePage {
|
|||||||
|
|
||||||
if (await this.canCloseTab(activeTab, closeButton)) {
|
if (await this.canCloseTab(activeTab, closeButton)) {
|
||||||
await closeButton.waitFor({state: 'visible', timeout: 5000});
|
await closeButton.waitFor({state: 'visible', timeout: 5000});
|
||||||
await this.safeClick(closeButton);
|
await this.clickByElement(closeButton);
|
||||||
await this.waitForTimeout(500);
|
await this.waitForTimeout(500);
|
||||||
} else {
|
} else {
|
||||||
console.log(`⚠️ [${parentMenu.text}] 没有找到可关闭的tab,继续执行...`);
|
console.log(`⚠️ [${parentMenu.text}] 没有找到可关闭的tab,继续执行...`);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user