2016-11-16 4 views
10

Я пытаюсь использовать async/await с protractor в TypeScript. Я следую примеру: https://github.com/angular/protractor/tree/master/exampleTypescript/asyncAwaitasync/ждут шаблона в транспортирнике

В моих экспериментах он отлично работает. Тем не менее, я должен использовать await для каждого звонка, связанного с взаимодействием браузера.

Например:

У меня есть объект страницы для страницы входа:

login.ts:

import {browser, element, by, By, $, $$, ExpectedConditions} from "protractor"; 
import { DashboardPage } from "./dashboard"; 
export class LoginPage { 
    usernameInput = element(by.id("username")); 
    passwordInput = element(by.id("password")); 
    loginButton = element(by.id("login_button")); 

    async get() { 
     await browser.get(login_url); 
     return this; 
    } 

    async getTitle() { 
     let title = await browser.getTitle(); 
     return title; 
    } 

    async typeUsername(username: string) { 
     await this.usernameInput.sendKeys(username); 
    } 

    async typePassword(password: string) { 
     await this.passwordInput.sendKeys(password); 
    } 

    async login() { 
     await this.loginButton.click(); 
     return new DashboardPage(); 
    } 
} 

LoginSpec.ts:

import {browser, element, by, By, $, $$, ExpectedConditions} from "protractor"; 
import { LoginPage } from "../pages/login"; 
describe("Login Page", function() { 

    beforeEach(() => { 
     // login page is not an angular page. 
     browser.ignoreSynchronization = true; 
    }); 

    afterEach(() => { 
     browser.ignoreSynchronization = false; 
    }); 

    it("should go to dashboard page after successfully login", async(): Promise<any> => { 
     let loginPage = new LoginPage(); 
     await loginPage.get(); 
     await loginPage.typeUsername(username); 
     await loginPage.typePassword(password); 
     let dashboard = await loginPage.login(); 
     expect(await dashboard.getTitle()).toEqual(`Dashboard`); 
    }); 
}); 

В вышеприведенном test spec, я должен использовать много await для всех вызовов взаимодействия с браузером. Это вводит много шаблонов для await.

Вопрос в том, есть ли идея или способ уменьшить шаблон? Также, это правильный способ использовать async/await с protractor?

+2

Ну, второй вариант - использовать цепочки обещаний, которые вводят намного больше шаблонов. Я думаю, что это чистый и читаемый код. Увидев ожидание, вы скажете, что исполнение дано так, что глобальное состояние может там измениться. –

+0

Если вы хотите использовать чистую карму, у вас есть возможность использовать узловые волокна –

+0

Это кажется мне хорошим. Imo 'await' на самом деле не является шаблоном. Если ваши методы 'loginPage' требуют времени для решения, вам нужно использовать ключевое слово' await', чтобы предотвратить блокирование основного потока. Таким образом, ваши тесты будут работать быстрее. – Randy

ответ

4

К сожалению, все эти ожидания не ожидаются - ваш код не будет синхронизирован должным образом. Есть несколько случаев, когда вы можете пропустить вставку, ожидая - но в большинстве случаев это необходимо, так как ожидается, ваши обещания планируются один за другим.

Async/Await по-прежнему полагается на обещания. Так что ваш код Await работает идентично этому:

it("should go to dashboard page after successfully login",(): Promise<any> => { 
    let loginPage = new LoginPage(); 
    return loginPage.get().then(() => { 
     return loginPage.typeUsername(username); 
    }).then(() => { 
     return loginPage.typePassword(password); 
    }).then(()=> { 
     return loginPage.login(); 
    }).then((dashboard)=> { 
     return expect(dashboard.getTitle()).toEqual(`Dashboard`); 
    }) 
}); 

Так считают ЖДЕТ как хороший синтаксическими над обещание цепочки: https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs#option-1-use-classic-promise-chaining

Но есть способ синхронизации без ввода ЖДЕТ \ thens \ Генераторы \ обратные вызовы , Он назывался «волокнами». К сожалению, транспортир не поддерживает, но WebdriverIO использует его для синхронизации кода: https://www.facebook.com/ProtractorAngularJS/posts/1950761568515087

1

Вы можете легко запустить их в последовательности без использования await, но я рекомендую придерживаться ждать для удобства чтения.

Вот как ваш код может выглядеть без await.

import { LoginPage } from "../pages/login"; 

describe("Login Page", function() { 

    // mutable crap 

    it("should go to dashboard page after successfully login",() => { 
     const loginPage = new LoginPage(); 

     const asyncs = [ 
      () => loginPage.get(), 
      () => loginPage.typeUsername(username), 
      () => loginPage.typePassword(password), 
      () => loginPage.login(), 
      (dashboard: Dashboard) => dashboard.getTitle() 
     ]; 

     const tilePromise = asyncs.reduce((promised, next) => promised.then(next)); 

     // note the return. this is required 
     return titlePromise.then(dashboardTitle => { 
      expect(dashboardTitle).toEqual('Dashboard'); 
     }); 
    }); 
}); 

Опять же, я думаю, что await является предпочтительным с точки зрения читаемости, но нет ничего на том языке, который предписывает, что вы его используете.

Смежные вопросы