Как сделать метод PageObject активным, как методы Притяжения

С транспортиром мы можем это сделать:

beforeEach(function() {
 browser.get(myLoginUrl);
 this.username = element(by.model('username'));
 this.password = element(by.model('password'));
 this.loginButton = element(by.css('[ng-click="login()"]'));

 this.username.sendKeys(...);
 this.password.sendKeys(...);
 this.loginButton.click();

 // i'm logged in
});

И это все будет работать, потому что каждый из вышеперечисленных методов будет для всех практических целей запускаться в последовательном порядке, каждый поочередно запускается.

Теперь я создал объект модели PageObject, чтобы смоделировать мою страницу входа, которая должна использоваться для проверки других страниц. Я пытаюсь выяснить, как заставить мои методы модели PageObject работать как методы транспортира, работающие в "серии".

В качестве части моего процесса входа возвращается идентификатор сеанса, который необходим для последующих HTTP-сообщений/сообщений. После входа в систему я хочу протестировать домашнюю страницу, поэтому у меня есть тестовый код, подобный этому, используя страницу входа в систему:

beforeEach(function() {
 // code from above has been refactored into a page object. here i can just
 // call loginPage.loginAs(...) and it will log the user in and return the
 // session id
 var sessionId = loginPage.loginAs('[removed_email]', 'mypassword');

 // construct the home PageObject with a sessionId because homePage.get() will
 // need to put the sessionId in the url
 homePage = new HomePage(sessionId);
});

// test we can access the page
it('is accessible', function() {
 homePage.get();

 expect(browser.getCurrentUrl()).toMatch(homePage.homePageRegex);
});

я хочу

homePage = new HomePage(sessionId)

ждать и не дожидаться

var sessionId = loginPage.loginAs(...)

успешно завершил и вернул действительный sessionId. Подобно тому, как работают сами транспортирующие элементы.

Используя что-то вроде:

loginPage.loginAs('[removed_email]', 'mypassword').then(function(sessionId) {
 homePage = new HomePage(sessionId);
});

не работает, потому что это приведет к тому, что функция beforeEach выйдет, а первая она() запустится и попытается выполнить homePage.get() до того, как будет установлен sessionId.

Я занимался:

browser.driver.controlFlow().execute(function() {...});

чтобы каким-то образом синхронизировать и выполнять код параллельно, но у меня есть рецепт.

Кто-нибудь знает, что делать, что я пытаюсь сделать?

Я пытаюсь избежать много чего() цепочки в разделе Control Flow в документе:

https://code.google.com/p/selenium/wiki/WebDriverJs#Understanding_the_API

2 ответа

Транспортир пытается скрыть тот факт, что большинство интересных методов фактически не делают то, что они говорят, а просто ставят в очередь обещание делать то, что вы просили. Таким образом, хотя код выглядит как его серийный запуск, его нет.

В вашем случае вы хотите использовать метод then() для инициализации HomePage:

loginPage.loginAs('[removed_email]', 'mypassword').then(function(sessionId) {
 homePage = new HomePage(sessionId);
});

Но, вам нужно сделать код в последующем it ждать, что then, чтобы закончить. then метод возвращает обещание по этой причине (см. Документ WebDriverJS).

Итак, сохраните обещание от тогдашнего. Вы также можете использовать это обещание, чтобы передать результат, поэтому я собираюсь назвать обещание homePage (но прочитайте его, как и большинство результатов Protractor, как "обещание на домашнюю страницу").

var homePage;

...

homePage = loginPage.loginAs('[removed_email]', 'mypassword').then(function(sessionId) {
 return new HomePage(sessionId); // return the page via the promise
});

И затем сцепите это обещание в своем тесте:

homePage.then(function(page) {
 page.get();

 expect(browser.getCurrentUrl()).toMatch(page.homePageRegex);
});

Я был довольно уверен в своем ответе до последней части (где вы также хотите использовать страницу homePageRegex в ожидании). Я думаю, вы можете включить, что внутри then, но я предполагаю, что я не был бы слишком удивлен, если он не работает...

Кроме того, я не думаю, что есть особые предостережения по обмену обещаниями через it/beforeEach блоком. Но я мог бы что-то упустить...


вы сделали loginA возвратите обещание? Тогда вы можете сделать

beforeEach(function() {
 loginPage.loginAs('[removed_email]', 'mypassword').
 then(function(sessionId) {
 homePage = new HomePage(sessionId);
 });
});

licensed under cc by-sa 3.0 with attribution.