Вот структура моей инфраструктуры автоматизации пользовательского интерфейса.Это Typescript, компилируемый в Protractor.
3 Спецификации:
Каждый Импорт из объектов страницы, помощников приложения и помощников фреймворка
Объекты страницы: Импорт функций из помощника.Импорт функций из помощника приложения.// Комментируя это, творит чудеса и не выдает ошибок
Функции Framework Helper: Просто функции.
Функции Application Helper: Импорт функций изпомощник.
Я читал, что если будет слишком много функций, это произойдет.Но это необходимо для того, чтобы мой фреймворк не превратился в грязный неуправляемый код.
Как этого избежать?Каковы лучшие практики?
Ошибка:
× encountered a declaration exception
- RangeError: Maximum call stack size exceeded
Кроме того, при такой сложной структуре
debugger;
просто не работает.
Пример кода:
describe('My app', () => {
debugger;
let login = new LoginPage(),//Has a few functions
dashboard = new DashboardPage(); //Has a few functions
// myApp: myAppHelper = new myAppHelper();//Has a few functions. Called in all the page object files. If commented everywhere except 1 then works fine.
//There are just 3 spec files and 3 page objects. No infinite loops anywhere and everything is quite straightforward.
beforeEach(async () => {
browser.ignoreSynchronization = true;
});
afterEach(async () => {
await console.log("Step completed.")
});
it('open all admin pages', async () => {
try {
browser.pause();
// await myApp.login();
await login.loginToMyApp('UserID', 'Password');
await browser.sleep(5000);
// await dashboard.openAdminPurposes();
await browser.sleep(5000);
// await dashboard.openAdminmyAppProcesses();
await browser.sleep(5000);
}
catch (error) {
console.log("Open admin pages failed." + error);
}
});
Помощник по применению
/**
* A library of reusable functions that can be used across the abc.
* Do NOT add any functions that are related to the automation framework.
*/
import { browser, by, WebElement, element } from 'protractor';
import { Helper } from './helper';
import { DashboardPage } from './page-objects/abc/dashboard-page';
export class myAppHelper {
helper: Helper = new Helper();
dashboardPage: DashboardPage = new DashboardPage();
currentEnvironment: string = "beta";
serverURL: string = this.setServerURL(this.currentEnvironment);
subSt: string = "/v3/abc/view/";
adminSt: string = "/v3/abc/admin/";
URL: string = this.serverURL;
setServerURL(env: string): string {
if (env.toLowerCase() == "beta") {
return this.serverURL = "https://beta-abcde.abc.com";
}
else {
return this.serverURL = "https://abcde.abc.com";
}
}
async login(): Promise<void> {
await browser.get(this.URL);
}
async gotoDashboard(): Promise<void> {
await browser.get(this.URL + this.subSt + "dashboard");
await this.helper.compareText(this.dashboardPage.dashboardHeader, "Dashboard");
}
async gotoProjectsList(): Promise<void> {
await browser.get(this.URL + this.subSt + "projects");
}
//Admin Pages
async gotoAdminPurposes(): Promise<void> {
await browser.get(this.URL + this.adminSt + "purposes");
}
}
//The rest of the functions are application specific but you get the idea.
}
Помощник
/**
* A library of reusable functions that can be used across the framework.
* Do NOT add any functions that are project/module specific.
*/
import { browser, WebElement } from 'protractor';
export class Helper {
async enterText(aelement: WebElement, textToEnter: string): Promise<void> {
await browser.sleep(1000);
await aelement.sendKeys(textToEnter);
}
async click(aelement: WebElement): Promise<void> {
try {
await browser.sleep(1500);
await aelement.click();
}
catch (error) {
console.log("Error in click: " + error);
}
}
async readText(element: WebElement): Promise<string> {
var elementText = await element.getText().then(function(text) {
console.log("ReadText is : " + text);
return text;
});
return elementText;
});
}
}