Как изменить дату браузера в транспортире
Мой вариант использования состоит в том, что у меня есть пользовательский интерфейс, который предотвращает операцию B, если операция A не произошла в предыдущем календарном месяце (безумие учета жизненного цикла - не имеет значения).
Я пишу тест, который проверяет, что операция B работает правильно, но я не могу выполнить операцию B, если у меня нет операции A, которая произошла в прошлом месяце. Моя настройка транспортира выполняется поверх настоящих API, и я не рассматриваю вариант подделки данных (если бы я решил смоделировать ответы API, это было бы проще).
API-интерфейсы не позволяют мне манипулировать датами создания / обновления операции A, поэтому я могу протестировать этот сценарий, чтобы манипулировать базовой БД или выдвигать браузер в следующем месяце во время тестирования. Предполагая, что я хочу использовать браузерный подход, как я могу заставить это работать с транспортиром?
1 ответ
После того, как у меня есть механизм для управления временем браузера, я выбрал решение запустить сценарий, выполнить операцию A, увеличить время браузера до одного месяца в будущем, а затем выполнить операцию B.
Это связано с использованием транспортиров browser.executeScript
запустить JS в контексте браузера и переопределить объект Date JS с помощью модуля timeshift-js.
Вот код
Этот код использует:
- угловой: 1.5.10
- транспортир: 5.1.2
- cucumber-js: 1.3.3
- timeshift-js: 1.0.1
Я могу написать сценарии, как это:
Feature: Travelling in time
Scenario: Scenario that manipulates time
When I view some page
And I check what time it is
And I do operation A
And I advance the browser by 1 days
And I check what time it is
Then I can do operation B
Scenario: Scenario Double Check that the next scenario gets the correct time
When I view the list of maintenance requests
And I check what time it is
И вот шаг реализации. Здесь нет ничего специфического для огурца, поэтому его легко адаптировать к основам описания / it на основе жасмина или мокко:
const timeShiftLibraryString = fs.readFileSync(`path/to/node_modules/timeshift-js/timeshift.js`, 'utf-8')
module.exports = function () {
this.When(/I advance the browser by (-?[0-9]+) (day|month)s?$/, function (offset, unit) {
const now = moment()
const future = moment().add(offset, unit)
const amountOfMillisecondsToAdvanceBrowser = (future.unix() - now.unix()) * 1000
const tolerance = 15 * 1000
const advanceTime = function (futureOffsetInMilliseconds, timeShiftLibraryString) {
// these two lines are only necessary because I dont want Timeshift in my production code, only during test
const timeshiftLibrary = new Function(timeShiftLibraryString)
timeshiftLibrary.call(window)
Date = window.TimeShift.Date
window.TimeShift.setTime(Date.now() + futureOffsetInMilliseconds)
return Date.now()
}
return browser.executeScript(advanceTime, amountOfMillisecondsToAdvanceBrowser, timeShiftLibraryString).then((browserTime) => {
const expectedTime = Date.now() + amountOfMillisecondsToAdvanceBrowser - tolerance
this.logger.debug(`Time manipulation complete: browserTime = ${moment(browserTime)}`)
if (browserTime >= expectedTime) {
return Promise.resolve(browserTime)
}
return Promise.reject(new Error(`advanceTime did not work: reported browserTime: ${browserTime}. Expected Time: ${expectedTime}`))
})
})
this.When(/I check what time it is/, function () {
const whatTimeIsItInTheBrowser = function () {
return Date.now()
}
return browser.executeScript(whatTimeIsItInTheBrowser).then((browserTime) => {
console.log(`Browser Time = ${moment(browserTime)}`)
})
})
}
Соображения:
- сложная часть сериализации библиотеки timeshift-js. Я не хотел упаковывать его с моим приложением, так что это означало, что мне пришлось вводить его по требованию во время теста
- вы не увидите журналы браузера, если явно не зайдете и не получите их, используя https://github.com/angular/protractor/blob/master/docs/faq.md#how-can-i-get-hold-of-the-browsers-console
- Вы не можете манипулировать временем браузера, пока не сделали хотя бы одну страницу, браузер должен загрузить некоторые HTML и JS, прежде чем вы сможете манипулировать датой в контексте JS браузера.