Как изменить дату браузера в транспортире

Мой вариант использования состоит в том, что у меня есть пользовательский интерфейс, который предотвращает операцию 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 браузера.
Другие вопросы по тегам