Tìm kiếm trang web

typescript - mẫu khởi tạo async/await trong protractor


Tôi đang cố gắng sử dụng async/await với protractor trong TypeScript. Tôi đang theo ví dụ tại: https://github.com/angular/protractor/tree/master/exampleTypescript/asyncAwait

Nó hoạt động tốt trong các thí nghiệm của tôi. Tuy nhiên, tôi phải sử dụng await trên mọi lần gọi liên quan đến tương tác với trình duyệt.

Ví dụ:

Tôi có một đối tượng trang cho trang đăng nhập:

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`);
    });
});

Trong đặc tả kiểm thử ở trên, tôi phải sử dụng nhiều await cho tất cả các lần gọi tương tác với trình duyệt. Điều đó tạo ra rất nhiều mã lặp cho await.

Câu hỏi là, có ý tưởng hoặc cách nào để giảm khối mã lặp đi lặp lại không? Ngoài ra, đây có phải là cách đúng để sử dụng async/await với protractor không?

Câu trả lời #1

Thật không may, nếu thiếu tất cả những lệnh await này - mã của bạn sẽ không được đồng bộ hóa đúng cách. Có một vài trường hợp bạn có thể bỏ lỡ việc thêm await - nhưng trong hầu hết các trường hợp điều này là cần thiết, vì await khiến các promise của bạn thực hiện theo từng cái một.

Async/Await vẫn dựa vào Promises. Vì vậy mã await của bạn hoạt động giống hệt như sau:

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`);
    })
});

Vì vậy hãy xem consider awaits như một cách viết cú pháp đẹp hơn cho việc chuỗi promise: https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs#option-1-use-classic-promise-chaining

Nhưng có một cách để đồng bộ mà không cần sử dụng awaits\thens\generators\callbacks. Nó được gọi là 'fibers'. Thật không may, protractor không hỗ trợ điều này, nhưng WebdriverIO sử dụng nó để đồng bộ mã: https://www.facebook.com/ProtractorAngularJS/posts/1950761568515087

Câu trả lời #2

Bạn có thể dễ dàng chạy chúng theo thứ tự mà không cần sử dụng await, nhưng tôi khuyên bạn nên dùng await để dễ đọc hơn.

Đây là cách mã của bạn có thể trông như thế nào mà không có 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');
        });
    });
});

Một lần nữa, tôi nghĩ await là tốt hơn về mặt khả năng đọc, nhưng không có gì trong ngôn ngữ bắt buộc bạn phải sử dụng nó.

Bài viết liên quan