Playwright POM架构下TypeError: 无法读取'page'属性问题求助
Playwright POM 报错排查:TypeError: Cannot read properties of undefined (reading 'page')
你在使用Playwright页面对象模型(POM)编写自动化测试时,遇到如下错误:
TypeError: Cannot read properties of undefined (reading 'page')
错误指向创建POM_Manager实例的代码行,完整错误栈:
8 | const password = "SDKsdk-122"; 9 | > 10 | const pom_Manager = new POM_Manager(page); | ^ 11 | /****************** Login Page - START *******************/ 12 | const loginPage = pom_Manager.getLoginPage(); 13 | await loginPage.goTo(); at new LoginPage (C:\Users\escamilr\Desktop\CDKHubAutomation\pageobjects\LoginPage.js:6:28) at new POM_Manager (C:\Users\escamilr\Desktop\CDKHubAutomation\pageobjects\POM_Manager.js:17:22) at C:\Users\escamilr\Desktop\CDKHubAutomation\tests\CDKLogin.spec.js:10:25
问题根源
错误出在LoginPage和MultifactorPage的构造函数中:
- 错误地将页面元素挂载到
this.page对象上,而非类实例自身(this) - 存在语法错误:比如
this.page.signInbutton.page.locator这种链式调用错误,正确写法应该是直接用page.locator()赋值给this的属性 - 测试用例中存在方法名不匹配问题:调用了
loginPage.goTo(),但LoginPage中定义的方法是goToApplication
修复后的代码
1. 修复LoginPage.js
class LoginPage { constructor(page) { this.page = page; // 修正:将元素挂载到类实例this上,而非this.page this.signInbutton = page.locator("[data-testid='primary-button']"); this.userName = page.locator("#emailId"); this.password = page.locator("#password"); } async goTo() { // 重命名方法,和测试用例调用一致 const applicationURL = "https://www-dit.connectcdk.com/a/hub/#/"; console.log('Go to application: ' + applicationURL); await this.page.goto(applicationURL); } async validLogin(username, password) { console.log('Filling ' + username + ' in Username textBox'); await this.userName.type(username); console.log('Filling ' + password + ' in Password textBox'); await this.password.type(password); // 修正:之前误操作了用户名输入框 console.log('Clicking on Sign in button') await this.signInbutton.click(); await this.page.waitForLoadState('networkidle'); } } module.exports = { LoginPage };
2. 修复MultifactorPage.js
class MultifactorPage { constructor(page) { this.page = page; // 修正:将元素挂载到类实例this上,修复语法错误 this.skipButton = page.locator('button:has-text("Skip")'); this.contactTxtbox = page.locator("#infoField"); this.nextButton = page.locator('button:has-text("Next")'); } async skipContact() { await this.skipButton.click(); await this.page.waitForLoadState('networkidle'); } //Add add email & contact methods respectively } module.exports = { MultifactorPage };
3. 测试用例CDKLogin.spec.js(方法名已匹配,无需额外修改)
const {test, expect} = require('@playwright/test'); const {POM_Manager} = require('../pageobjects/POM_Manager'); test('Client App login', async ({page})=> { const username = "fidler@autocan.ca"; const password = "SDKsdk-122"; const pom_Manager = new POM_Manager(page); /****************** Login Page - START *******************/ const loginPage = pom_Manager.getLoginPage(); await loginPage.goTo(); await loginPage.validLogin(username,password); /****************** Login Page - END *******************/ /****************** Skip Multifactor Option - START *******************/ const multifactorPage = pom_Manager.getMultifactorPage(); await multifactorPage.skipContact(); });
关键修复点总结
- 所有页面元素必须挂载到类实例的
this上,而非this.page - 修正链式调用错误:
page.locator()直接赋值给this.xxx,不要多写一层page - 测试用例中的方法调用必须和页面类中定义的方法名一致
- 修复LoginPage中密码输入框的错误调用(之前误操作了用户名输入框)
内容的提问来源于stack exchange,提问作者Resca1980
相关产品推荐
相关产品推荐

