У меня возникли проблемы с пониманием класса и способов использования объектов, прототипов и т. Д. В системе, которую я имею. Мне кажется, что я делаю все правильно, но это не работает, и я надеюсь, что кто-то сможет объяснить это мне или заставить меня указать в правильном направлении.Проблема с javascript, транспортиром и классами
Итак, вот что: Я пытаюсь создать общий объект страницы и объект проверки, который обрабатывал бы поле ввода со связанной текстовой меткой. Кажется, что все работает, если у меня есть проверка в том же классе, что и структура объектов страницы, но я недавно узнал, что это плохой дизайн.
Это угловой 2 сайт rc1. Я использую protractor 3.3.0 и обеспечил, чтобы версия проекта селена и хромирования была обновлена с помощью webdriver-manager.
Так вот что я сделал (имена файлов в комментариях в начале каждой секции):
'use strict';
/*
* InputLabelPageObject.js
*
* This object will provide basic methods for an Input box with an attached label.
* It is expected that the label will have an element called "label" and an element called "input"
*/
module.exports = InputLabelPageObject;
/**
* Create an object that will provide methods for an input/label combination of elements.
*
* @param container The selector for the __container of the input/label combination of elements.
*/
function InputLabelPageObject(container) {
this.Container = container;
}
InputLabelPageObject.prototype = {
constructor: InputLabelPageObject,
/**
* Return the element for the label of the input/label combination of elements.
*
* @returns {protractor.element}
*/
getLabel: function() {
return this.Container.$('label');
},
/**
* Return the element for the input of the input/label combination of elements.
*
* @returns {ElementFinder}
*/
getInput: function() {
return this.Container.$('input');
},
/**
* Return the text shown in the input of the input/label combination of elements.
*
* @returns {Promise}
*/
getValue: function() {
return this.getInput().getAttribute('value');
},
/**
* Get the placeholder text shown in the input of the input/label combination of elements.
*
* @returns {Promise}
*/
getPlaceholder: function() {
return this.getInput().getAttribute('placeholder');
},
/**
* Clears the input element then puts the text from data into the input element.
*
* @param data The text to be entered into the input element.
*/
sendKeys: function (data) {
var el = this.getInput();
el.clear().then(function() {
return el.sendKeys(data);
});
}
};
-
'use strict';
/*
* InputLabelVerification.js
*
* Provide verification methods associated with an Input and Label
* combination of elements.
*/
module.exports = InputLabelVerifications;
var inputLabelPageObject;
function InputLabelVerifications(inputLabelPageObject) {
this.__setPageObject(inputLabelPageObject);
}
InputLabelVerifications.prototype = {
constructor: InputLabelVerifications,
__setPageObject: function (ilpo) {
inputLabelPageObject = ilpo;
},
/**
* Verify the text on the label of the input/label combination of elements.
*
* @param expected The expected text on the label.
*/
verifyText: function (expected) {
//console.log('Asserting text [' + expected + ']');
expect(inputLabelPageObject.getLabel()).toEqual(expected);
},
/**
* Verify the text shown in the input of the input/label combination of elements.
*
* @param expected The expected text in the input element.
*/
verifyValue: function (expected) {
//console.log('Asserting input value [' + expected + ']');
expect(inputLabelPageObject.getValue()).toEqual(expected);
},
/**
* Verify the placeholder text shown in the input of the input/label combination of elements.
*
* @param expected The expected text of the placeholder.
*/
verifyPlaceholder: function (expected) {
//console.log('Verifying placeholder text [' + expected + ']');
expect(inputLabelPageObject.getPlaceholder()).toEqual(expected);
}
};
-
'use strict';
/*
* LoginPageObject.js
*
*/
var InputLabelPageObject = require('./generics/InputLabelPageObject.js');
module.exports = LoginPageObject;
var __container = $('login-component');
var username = new InputLabelPageObject(__container.$('form:nth-child(2) > div:nth-child(1)'));
var password = new InputLabelPageObject(__container.$('form:nth-child(2) > div:nth-child(2)'));
/**
* Create an object that contains the methods necessary to perform actions against the LoginPageObject page.
*
* @param url The base URL string. If not undefined, it will load the url+'/login' page.
* @constructor new LoginPageObject('http://localhost:9000');
*/
function LoginPageObject(url) {
if (url) {
this.loadPage(url)
}
}
LoginPageObject.prototype = {
constructor: LoginPageObject,
loadPage: function (url) {
url = url + '/login';
console.log('Loading page: '+ url);
browser.get(url);
},
welcome: {
/**
* Return the element for the Welcome text
*
* @returns {ElementFinder}
*/
get: function() {
return __container.$('section:first-child h1:first-child');
},
},
/**
* Return an InputLabelPageObject object specific for the username input and label elements.
*/
username: username,
/**
* Return an InputLabelPageObject object specific for the password input and label elements.
*/
password: password,
loginButton: {
/**
* Return the element for the login button.
*
* @returns {ElementFinder}
*/
get: function() {
return __container.$('form > button');
},
/**
* Click the LoginPageObject button.
* @returns {*|void|webdriver.promise.Promise<void>|ActionSequence|!webdriver.promise.Promise.<void>}
*/
click: function() {
return this.get().click();
}
}
};
-
'use strict';
/*
* LoginPageVerifications.js
*/
var LoginPageObject = require('../pageObjects/LoginPageObject');
var verifyText = require('./generics/VerifyText');
var inputLabelVerifications = require('./generics/InputLabelVerifications');
module.exports = LoginPageVerifications;
var __loginPageObject = new LoginPageObject();
function LoginPageVerifications(url) {
if (url) {
__loginPageObject = new LoginPageObject(url);
}
}
LoginPageVerifications.prototype = {
constructor: LoginPageVerifications,
loginPageObject: new LoginPageObject(),
welcome: {
verifyText: function (expected) {
verifyText(__loginPageObject.welcome.get(), expected);
}
},
username: new inputLabelVerifications(__loginPageObject.username),
password: new inputLabelVerifications(__loginPageObject.password),
loginButton: {
verifyText: function (expected) {
verifyText(__loginPageObject.loginButton.get(), expected);
}
},
/**
* Performs the actions of logging in. That is, enter the username and password values,
* then click the LoginPageObject button. This does *not* verify page load.
*
* @param username The username to login with.
* @param password The password to login with.
*/
doLogin: function (username, password) {
var uPromise = __loginPageObject.username.sendKeys(username);
var pPromise = __loginPageObject.password.sendKeys(password);
protractor.promise.asap(this.username.verifyValue(username));
protractor.promise.asap(this.password.verifyValue(password));
protractor.promise.all([uPromise, pPromise]).then(this.loginButton.click());
},
/**
* Verifies all page elements' text or other default attributes.
*
* @param welcomeText The expected Welcome text
* @param userText The expected username label text.
* @param userPlaceholder The expected username's input element's placeholder text.
* @param passText The expected password label text.
* @param passPlaceholder The expected password's input element's placeholder text.
* @param loginText The expected login button text.
*/
verifyPage: function (welcomeText, userText, userPlaceholder, passText, passPlaceholder, loginText) {
this.welcome.verifyText(welcomeText);
this.username.verifyText(userText);
this.username.verifyPlaceholder(userPlaceholder);
this.password.verifyText(passText);
this.password.verifyPlaceholder(passPlaceholder);
this.loginButton.verifyText(loginText);
}
};
-
'use strict';
/*
* login-spec.js
*/
var LoginPageVerifications = require('../components/actions/LoginPageVerifications');
var myUrl = 'http://localhost:3000';
describe('My Login Page test', function() {
var loginPage;
beforeAll(function() {
loginPage = new LoginPageVerifications(myUrl);
});
it('should verify username input and label values', function() {
var welcomeText = 'Thank you for visiting my login page';
var userText = 'Username';
var userPlaceholder = 'Enter your username';
var passText = 'Password';
var passPlaceholder = 'Enter your password';
var loginText = 'Login';
loginPage.username.verifyText(userText);
// loginPage.verifyPage(welcomeText, userText, userPlaceholder, passText, passPlaceholder, loginText);
});
});
Результаты, которые я обычно видящие: Если в InputLabelVerification.js я выхожу из var inputLabelPageObject
или попытаться установить значение только в функции конструктора, я получаю Failed: Cannot read property 'getLabel' of undefined
. Итак, я понял, что должен установить его так, как я показал выше.
Ближайший я, кажется, получаю, когда я получаю следующий ответ:
A Jasmine spec timed out. Resetting the WebDriver Control Flow.
F
Failures:
1) My Login Page test should verify username input and label values
Expected ({ ptor_: ({ controlFlow: Function, schedule: Function,
setFileDetector: Function, getSession: Function, getCapabilities: Function,
quit: Function, actions: Function, touchActions: Function,
executeScript: Function, executeAsyncScript: Function, call: Function,
wait: Function, sleep: Function, getWindowHandle... }) }) to equal 'Username'.
В разделе LoginPageVerification.js, я проверил и заверил, что другие проверки (радушные и loginButton) работают нормально.
Кроме того, если от входа-spec.js добавить эту строку:
expect(loginPage.loginPageObject.username.getLabel().getText()).toEqual(userText);
это ожидать проходит тест.
У меня есть ответ. И теперь я чувствую себя глупо. Я отправлю как ответ, когда смогу через 2 дня. (Это заняло у меня несколько дней, чтобы все было правильно.) По сути, я вызываю '.getLabel()' из 'InputLabelPageObject' из' InputLabelVerifications', который возвращает ElementFinder ... он НЕ возвращает строку, как есть необходимо. В InputLabelPageObject я добавил следующую строку: 'getText: function() {this.getLabel(). GetText(); } ', а затем вызвал функцию getText()' в объекте проверки, и все работает как ожидалось. – Machtyn