Spec-Zone.ru › Cypress

должен

Создать утверждение. Утверждения автоматически повторяются до тех пор, пока они не пройдут или не истечёт время ожидания.

Псевдоним .and()

Примечание: .should() предполагает, что вы уже знакомы с основными понятиями, такими как утверждения

Синтаксис

.should(chainers)
.should(chainers, value)
.should(chainers, method, value)
.should(callbackFn)

Использование

Правильное использование

cy.get('.error').should('be.empty') // Assert that '.error' is empty
cy.contains('Login').should('be.visible') // Assert that el is visible
cy.wrap({ foo: 'bar' }).its('foo').should('eq', 'bar') // Assert the 'foo' property equals 'bar'

Неправильное использование

cy.should('eq', '42') // Should not be chained off 'cy'

Аргументы

chainers (Строка)

Любой допустимый цепной метод, который происходит из Chai или Chai-jQuery или Sinon-Chai.

value (Строка)

Значение для проверки с использованием цепного метода.

method (Строка)

Метод, который должен быть вызван для цепного метода.

callbackFn (Функция)

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

Возвращаемые значения

  • В большинстве случаев, .should() возвращает тот же объект, который был передан из предыдущей команды.
cy.get('nav') // yields <nav>
  .should('be.visible') // yields <nav>

Однако, некоторые цепные методы изменяют объект. В примере ниже, второе .should() возвращает строку sans-serif, потому что цепной метод have.css, 'font-family' изменяет объект.

cy.get('nav') // yields <nav>
  .should('be.visible') // yields <nav>
  .should('have.css', 'font-family') // yields 'sans-serif'
  .and('match', /serif/) // yields 'sans-serif'

Примеры

Цепные методы

Проверить, что флажок отключён

cy.get(':checkbox').should('be.disabled')

Возвращается текущий DOM-элемент

cy.get('option:first')
  .should('be.selected')
  .then(($option) => {
    // $option is yielded
  })

Значение

Проверить, что класс равен 'form-horizontal'

cy.get('form').should('have.class', 'form-horizontal')

Проверить, что значение не равно 'Jane'

cy.get('input').should('not.have.value', 'Jane')

Возвращается текущий объект

cy.get('button')
  .should('have.id', 'new-user')
  .then(($button) => {
    // $button is yielded
  })

Метод и значение

Проверить, что у элемента есть атрибут href

// have.attr comes from chai-jquery
cy.get('#header a').should('have.attr', 'href')

Проверить, что значение атрибута href равно '/users'

cy.get('#header a').should('have.attr', 'href', '/users')

Примечание: утверждение have.attr изменяет объект с исходного элемента на значение атрибута

cy.get('#header a') // yields the element
  .should('have.attr', 'href') // yields the "href" attribute
  .and('equal', '/users') // checks the "href" value

Фокус

Проверить, что поле ввода получает фокус после нажатия кнопки

cy.get('#btn-focuses-input').click()
cy.get('#input-receives-focus').should('have.focus') // equivalent to should('be.focused')

Функция

Передача функции в .should() позволяет выполнить несколько проверок на возвращаемом объекте. Это также даёт возможность изменять проверяемые значения.

Убедитесь, что в вашей функции обратного вызова нет кода, который вызывает побочные эффекты. Функция обратного вызова будет повторно выполняться снова и снова, пока никакие утверждения в ней не вызовут ошибку.

Проверить длину, содержимое и классы из множества <p>

<div>
  <p class="text-primary">Hello World</p>
  <p class="text-danger">You have an error</p>
  <p class="text-default">Try again later</p>
</div>
cy.get('p').should(($p) => {
  // should have found 3 elements
  expect($p).to.have.length(3)

  // make sure the first contains some text content
  expect($p.first()).to.contain('Hello World')

  // use jquery's map to grab all of their classes
  // jquery's map returns a new jquery object
  const classes = $p.map((i, el) => {
    return Cypress.$(el).attr('class')
  })

  // call classes.get() to make this a plain array
  expect(classes.get()).to.deep.eq([
    'text-primary',
    'text-danger',
    'text-default',
  ])
})

Предупреждение Любое значение, возвращаемое функцией обратного вызова .should(), будет проигнорировано. Исходный объект будет возвращён следующей команде.

cy.get('p')
  .should(($p) => {
    expect($p).to.have.length(3)

    return 'foo'
  })
  .then(($p) => {
    // the argument $p will be the 3 elements, not "foo"
  })

Проверить, что имя класса содержит heading-

<div class="docs-header">
  <div class="main-abc123 heading-xyz987">Introduction</div>
</div>
cy.get('.docs-header')
  .find('div')
  // .should(cb) callback function will be retried
  .should(($div) => {
    expect($div).to.have.length(1)

    const className = $div[0].className

    expect(className).to.match(/heading-/)
  })
  // .then(cb) callback is not retried,
  // it either passes or fails
  .then(($div) => {
    expect($div).to.have.text('Introduction')
  })

Вы даже можете генерировать собственные ошибки из функции обратного вызова.

cy.get('.docs-header')
  .find('div')
  .should(($div) => {
    if ($div.length !== 1) {
      // you can throw your own errors
      throw new Error('Did not find 1 element')
    }

    const className = $div[0].className

    if (!className.match(/heading-/)) {
      throw new Error(`No class "heading-" in ${className}`)
    }
  })

Проверить текстовое содержимое 3 элементов

В примере ниже сначала проверяется, что элементов 3, а затем проверяется текстовое содержимое каждого из них.

<ul class="connectors-list">
  <li>Walk the dog</li>
  <li>Feed the cat</li>
  <li>Write JavaScript</li>
</ul>
cy.get('.connectors-list > li').should(($lis) => {
  expect($lis).to.have.length(3)
  expect($lis.eq(0)).to.contain('Walk the dog')
  expect($lis.eq(1)).to.contain('Feed the cat')
  expect($lis.eq(2)).to.contain('Write JavaScript')
})

Прочитайте Cypress should callback пост блога, чтобы увидеть больше вариантов вышеупомянутого примера.

Для ясности, вы можете передать строковое сообщение в качестве второго аргумента к любому утверждению expect, см. Chai#expect.

cy.get('.connectors-list > li').should(($lis) => {
  expect($lis, '3 items').to.have.length(3)
  expect($lis.eq(0), 'first item').to.contain('Walk the dog')
  expect($lis.eq(1), 'second item').to.contain('Feed the cat')
  expect($lis.eq(2), 'third item').to.contain('Write JavaScript')
})

Эти строковые сообщения будут отображаться в журнале команд, придавая каждому утверждению больше контекста.

Expect assertions with messages

Сравнение текстовых значений двух элементов

В примере ниже извлекается текст, содержащийся в одном элементе, и сохраняется в переменной закрытия. Затем тест извлекает текст из другого элемента и утверждает, что два текстовых значения одинаковы после нормализации.

<div class="company-details">
  <div class="title">Acme Developers</div>
  <div class="identifier">ACMEDEVELOPERS</div>
</div>
const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase()

// will keep text from title element
let titleText

cy.get('.company-details')
  .find('.title')
  .then(($title) => {
    // save text from the first element
    titleText = normalizeText($title.text())
  })

cy.get('.company-details')
  .find('.identifier')
  .should(($identifier) => {
    // we can massage text before comparing
    const idText = normalizeText($identifier.text())

    // text from the title element should already be set
    expect(idText, 'ID').to.equal(titleText)
  })

Множественные утверждения

Цепные утверждения

Cypress упрощает цепочку утверждений.

В этом примере мы используем .and(), что идентично .should().

// our subject is not changed by our first assertion,
// so we can continue to use DOM based assertions
cy.get('option:first').should('be.selected').and('have.value', 'Metallica')

Ожидание выполнения утверждений

Cypress не разрешит ваши команды, пока все утверждения не пройдут.

// Application Code
$('button').click(function () {
  $button = $(this)

  setTimeout(() => {
    $button.removeClass('inactive').addClass('active')
  }, 1000)
})
cy.get('button')
  .click()
  .should('have.class', 'active')
  .and('not.have.class', 'inactive')

Примечания

Объекты

Как узнать, какие утверждения меняют объект, а какие нет?

Цепные методы, полученные из Chai или Chai-jQuery всегда будут документировать то, что они возвращают.

Использование функции обратного вызова не изменит то, что возвращается

Всё, что возвращается в функции, игнорируется. Cypress всегда заставляет команду возвращать значение от предыдущей команды cy (которое в примере ниже — <button>)

cy.get('button')
  .should(($button) => {
    expect({ foo: 'bar' }).to.deep.eq({ foo: 'bar' })

    return { foo: 'bar' } // return is ignored, .should() yields <button>
  })
  .then(($button) => {
    // do anything we want with <button>
  })

Различия

В чём разница между .then() и .should()/.and()?

Использование .then() позволяет использовать возвращаемый объект в функции обратного вызова и должно использоваться, когда нужно манипулировать значениями или выполнять какие-либо действия.

При использовании функции обратного вызова с .should() или .and(), с другой стороны, есть специальная логика для повторного выполнения функции обратного вызова до тех пор, пока ни одно утверждение в ней не выбросит ошибку. Вы должны быть осторожны с побочными эффектами в функции обратного вызова .should() или .and(), которые вы не хотите выполнять многократно.

Правила

Требования

  • .should() требует цепочки с предыдущей командой.

Таймауты

  • .should() будет продолжать повторные попытки указанных утверждений до истечения времени ожидания.
cy.get('input', { timeout: 10000 }).should('have.value', '10')
// timeout here will be passed down to the '.should()'
// and it will retry for up to 10 secs
cy.get('input', { timeout: 10000 }).should(($input) => {
  // timeout here will be passed down to the '.should()'
  // unless an assertion throws earlier,
  // ALL of the assertions will retry for up to 10 secs
  expect($input).to.not.be('disabled')
  expect($input).to.not.have.class('error')
  expect($input).to.have.value('US')
})

Журнал команд

Утверждение о том, что в навигации должно быть 8 дочерних элементов

cy.get('.left-nav>.nav').children().should('have.length', 8)

Приведённые выше команды будут отображаться в журнале команд как:

Command Log should

При нажатии на assert в журнале команд, консоль выведет следующее:

Console Log should

История

Версия Изменения
0.11.4 Разрешает аргумент функции обратного вызова
< 0.3.3 .should() команда добавлена

См. также

  • .and()
  • Руководство: Введение в Cypress
  • Справочник: Список утверждений
  • cypress-example-kitchensink Утверждения

© 2017 Cypress.io
Licensed under the MIT License.
https://docs.cypress.io/api/commands/should

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API