Как мне реализовать Typescript webdriverio для SpectronClient?

Spectron - это фреймворк node.js для автоматизации приложений Electron. Я использую Spectron вместе с AVA и Typescript для автоматического тестирования интеграции. Я использую метод подсказки AVA для обеспечения безопасности типов контекста теста, но не могу понять, как обеспечить безопасность типов в свойстве клиента Spectron, которое является клиентом http://webdriver.io/. Я могу видеть только несколько свойств, которые предоставляет файл определения машинописного текста Spectron, и это вызывает ошибки переноса машинописного текста.

Вот ошибки, которые я получаю:

src/pages/drive-shell.ts(7,34): error TS2339: Property 'waitForVisible' does not exist on type 'SpectronClient'.
src/pages/login.ts(7,34): error TS2339: Property 'waitForVisible' does not exist on type 'SpectronClient'.
src/pages/login.ts(11,21): error TS2339: Property 'setValue' does not exist on type 'SpectronClient'.
src/pages/login.ts(12,21): error TS2339: Property 'setValue' does not exist on type 'SpectronClient'.
src/pages/login.ts(13,21): error TS2339: Property 'click' does not exist on type 'SpectronClient'.

3 ответа

Решение

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

Мне нужно, чтобы получить печатные издания для веб-драйвера IO

npm i -S @types/webdriverio

а затем я импортировал этот тип в мой login.ts сценарий и использовать его в качестве SpectronClient

import * as WebdriverIO from 'webdriverio';
export class Login {
    constructor(private client: WebdriverIO.Client<void>) { }

    public async waitForPageToLoad() {
        return await this.client.waitForVisible('#username');
    }

    public login(username: string, password: string) {
        this.client.setValue('#username', username);
        this.client.setValue('#Password', password);
        this.client.click('#login');
    }
}

а вот мой полный test.ts тестовый скрипт

import * as ava from 'ava';
import { Application } from 'spectron';
import { Login } from './pages/login';
import { Settings } from './settings';

function contextualize<T>(getContext: () => Promise<T>): ava.RegisterContextual<T> {
    ava.test.beforeEach(async (t) => {
        Object.assign(t.context, await getContext());
    });
    return ava.test;
}
const test = contextualize(async () => {
    const app = new Application({
        path: '../electron.exe',
        args: ['../app/index.html'],
    });
    await app.start();
    return { app };
});

test.afterEach.always(async (t) => await t.context.app.stop());

test('can login', async (t) => {
    const login = new Login(t.context.app.client);
    await login.waitForPageToLoad();
    login.login(Settings.username, Settings.password);
});

На данный момент (июль 2019 г.) WebdriverIO перешел на версию 5.0, но Spectron по-прежнему использует WebdriverIO 4. Для решения этой проблемы обязательно укажите версию, используемую в Spectron, при установке типов WebdriverIO:

npm i -S @types/webdriverio@^4.8.0

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

Здесь ясно сказано:

Spectron использует WebdriverIO и предоставляет управляемое свойство клиента для созданных экземпляров приложения. Клиентский API - это объект браузера WebdriverIO.

Но, как видно из документации WebdriverIO, такие функции, как click, setValueи т. д. не входят в browserобъект. Они доступны подelementобъект . Итак, вот что я сделал,

      const inputText = await app.client.$('user_name'); // get hold of the element
inputText.click(); // get access to the WebdriverIO functions
Другие вопросы по тегам