我正在使用 Cucumber 和 Playwright。我需要通过 BeforeAll 钩子中的 Playwright 启动 Chromium 浏览器,并将浏览器实例传递给页面对象,以便它们可以控制浏览器。
这是项目结构:
project_folder:
|_ _build // <= compiled files
|_ configs
|_ node_module
|_ src
|_ features
|_ page_objects
|_ step_definitions
|_ utils
|_ hooks.ts
|_ package.json
|_ tsconfig.json
hooks.ts:
let browserPage: Page;
let pages: PageFactory;
BeforeAll({timeout: 120000}, async function (){
const usersRoles = ['admin', 'publisher', 'advertiser', 'agency'];
for (const user of usersRoles) {
await saveLoginSession(user as User);
}
browserPage = await createBrowserPage('chrome', {headless: false});
pages = new PageFactory(browserPage);
});
Before({tags: '@skipAuth'}, async function () {
const browserName = process.env.BROWSER as 'chrome' | 'firefox' | 'webkit' || 'chrome';
browserPage = await createBrowserPage(browserName, {headless: false});
})
After(async function ({ pickle, result}) {
if (result!.status === Status.FAILED) {
await takeScreenshot.call(this, pickle, browserPage);
}
});
AfterAll(async function () {
await browserPage.close();
})
export {browserPage, pages};
pageFactory.ts:
export class PageFactory {
constructor(page: Page) {
this['Cognito page'] = new CognitoPage(page);
this['Dashboard page'] = new DashboardPage(page);
this['Home page'] = new LandingPage(page);
this['Login page'] = new LoginPage(page);
this['Campaign wizard'] = new CampaignWizard(page)
}
}
tsconfig.json:
{
"compilerOptions": {
"target": "ES2019",
"module": "CommonJS",
"moduleResolution": "Node",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitAny": false,
"skipLibCheck": true,
"typeRoots": [
"node_modules/@types"
],
"lib": ["ES6", "DOM", "ES2019"],
"outDir": "_build",
"resolveJsonModule": true,
"incremental": false
},
"include": ["configs", "src", "hooks.ts"],
"exclude": ["node_modules"],
"ts-node": {
"compilerOptions": {
"module": "commonjs"
}
}
}
黄瓜.cjs:
module.exports = {
default: {
formatOptions: {
snippetInterface: 'async-await'
},
paths: [
'src/features/'
],
dryRun: false,
require: [
'_build/src/step_definitions/**/*.js', // <= compiled files
'_build/hooks.js' // <= compiled files
],
requireModule: [
'ts-node/register'
],
format: [
'json:test-results/json-report.json',
'progress'
],
parallel: process.env.CI ? 10 : 1
}
}
package.json:
{
"name": "core-regression-bdd",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"pretest": "node _build/src/utils/report/reportInit.js",
"test": "cucumber-js --config=configs/cucumber.cjs || true",
"posttest": "node _build/src/utils/report/reporter.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@cucumber/cucumber": "^9.5.1",
"@playwright/test": "^1.38.0",
"@types/fs-extra": "^11.0.2",
"@types/node": "^20.8.0",
"fs-extra": "^11.1.1",
"multiple-cucumber-html-reporter": "^3.5.0",
"ts-node": "^10.9.1"
},
"dependencies": {
"dotenv": "^16.3.1"
}
}
当我运行测试时,我遇到浏览器未初始化(在 BeforeAll 挂钩中)并且收到此错误:
TypeError: Cannot read properties of undefined (reading 'locator')
at new DashboardPage (C:\Users\Jasurbek\Documents\Projects\core-regression-bdd\_build\src\page_objects\DashboardPage.js:10:30)
at new PageFactory (C:\Users\Jasurbek\Documents\Projects\core-regression-bdd\_build\src\page_objects\pageFactory.js:8:34)
at Object.<anonymous> (C:\Users\Jasurbek\Documents\Projects\core-regression-bdd\_build\src\step_definitions\campaignWizard.js:7:15)
at Module._compile (node:internal/modules/cjs/loader:1254:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
at Object.require.extensions.<computed> [as .js] (C:\Users\Jasurbek\
Documents\Projects\core-regression-bdd\node_modules\ts-node\src\index.ts:1608:43)
at Module.load (node:internal/modules/cjs/loader:1117:32)
at Function.Module._load (node:internal/modules/cjs/loader:958:12)
at Module.require (node:internal/modules/cjs/loader:1141:19)
at require (node:internal/modules/cjs/helpers:110:18)
保存会话.ts:
const { credentials: {currentEnv} } = secrets;
export async function saveLoginSession(coreUser: User) {
const page: Page = await createBrowserPage('chrome', {headless: false});
await authenticateInCognito(
secrets.credentials.cognito[currentEnv].username,
secrets.credentials.cognito[currentEnv].password,
page
);
await authenticateInCore(
secrets.credentials.core[`${coreUser.toLowerCase()}`].username,
secrets.credentials.core[`${coreUser.toLowerCase()}`].password,
page
);
await page.context().storageState({ path: `${path.resolve('session_data')}/${currentEnv}.${coreUser}.state.json`});
await page.context().clearCookies();
await page.close();
console.info(`💾 Successfully saved the session | ${coreUser}.state.json`);
}
createBrowserPage.ts:
import {Browser, chromium, firefox, webkit, LaunchOptions, Page} from "@playwright/test";
const browsers = {
chrome: chromium,
firefox,
webkit
}
export let browserInfo: { type?: string; version?: string } = {};
export async function createBrowserPage(browserName: 'chrome' | 'firefox' | 'webkit' = 'chrome', launchOptions?: LaunchOptions) {
const browser: Browser = process.env.browser
? await browsers[process.env.browser].launch(launchOptions)
: await browsers[browserName].launch(launchOptions);
const page: Page = await browser.newPage();
await page.setViewportSize({width: 1440, height: 780});
browserInfo['type'] = browser.browserType.toString()
browserInfo['version'] = browser.version.toString()
return page;
}
我将不胜感激任何帮助!
you can try
export const invokeBrowser = () =>{
const browserType=process.env.npm_config_BROWSER || process.env.PWG_ENV_BDD_BROWSER || 'chrome';
console.log(browserType);
// const browserType ='chrome';
switch (browserType) {
case 'chrome':
return chromium.launch(options);
case 'firefox':
return firefox.launch(options);
case 'webkit':
return webkit.launch(options);
default:
throw new Error('Please set the proper browser');
}
};
Call in
BeforeAll
BeforeAll(async function() {
rpApiPage=new ReportPortalPage();
console.log('BeforeAll Start>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ');
const tags: any = Constants.getRpTags();
// browser = `enter code here`await chromium.launch({ headless:false });
getEnv();
browser = await invokeBrowser();
});