В моей тестовой среде у меня были похожие проблемы. Мне нужно было получить доступ к внутренней функциональности приложения, например, для проверки того, был ли выполнен определенный запрос.
Окончательное решение состояло в том, чтобы раскрыть функциональность через window
объект. Тесты могут получить доступ к window
, используя browser.executeScript()
.
Учебник
в веб-приложении:
- Создайте
class
со всеми функциями, которые вы хотите использовать в тестах protractor
. В этом конкретном случае мы хотим передать строку в веб-приложение, зарегистрировать ее и передать обратно в тесты.
export class E2EDriver {
public give_id_back = async (id: string): Promise<string> => {
// Application internal logic here. We can access anything since we are
// within the real application.
console.log("Driver is running something within web-application!, id:",id)
return id
}
}
- внедрить этот класс в
window
объект.
const global = window as any
global.e2e_driver = new E2EDriver()
в рамках испытаний транспортира:
Теперь объект window содержит недавно добавленный класс E2EDriver
. Пришло время получить доступ
водителю в наших тестах:
- Создать мост через
browser.executeScript()
// This is a string of code which is passed to browser.executeAsyncScript()
const javascript_run_driver_fn = `
// remove function name from args
var args = [...arguments].splice(1);
// remove callback provided by protractor from args
var cb = args.splice(args.length-1, 1)[0];
// invoke requested function with given args and respond using cb()
e2e_driver[arguments[0]](...args).then(cb).catch(cb);
`;
// the real bridge..
const run_in_driver = async <T = void>(_browser: ProtractorBrowser, key: string, ...args: any[]): Promise<T> => {
return await _browser.executeAsyncScript<T>(javascript_run_driver_fn, key, ...(args || []))
}
let driver: E2EDriver = null
// For gettign access to the driver in protractor tests.
export class E2eDriverApi {
public static driver = async (_browser: ProtractorBrowser): Promise<E2eDriver> => {
if(driver) {
return driver
}
// get existing e2e-driver functions
const real_driver = await _browser.executeScript<E2eDriver>("return e2e_driver;")
const test_driver = { }
// expose functions from real_driver using browser.executeScript() API
// this creates the bridge..
Object.keys(real_driver).forEach(k => {
test_driver[k] = (...args: any[]) => run_in_driver(_browser, k, ...args)
})
driver = test_driver as E2eDriver
return driver
}
}
Этот код берет объект e2e_driver
из window
и упаковывает его в новый объект. В этом новом объекте все функции будут выполнены с использованием browser.executeAsyncScript()
, и его результаты будут возвращены.
К сожалению, E2EDriver
ограничен использованием функций, возвращающих Promise
, так как мы используем этот async
api.
- Использовать драйвер в некоторых тестах:
import { E2eDriverApi } from "./path/to/file"
import { browser } from "protractor"
describe("Given, web application", () => {
describe("When started", () => {
it("should e2e-driver be available", async () => {
const driver = await E2eDriverApi.driver(browser)
const id = await driver.give_id_back("I should be written to console")
expect(id).toEqual("I should be written to console")
})
})
})
Надеюсь, это поможет.
Спросите, если что-то неясно.
веселит.!