te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - How do interact correctly with a range input (slider) in Cypress? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do interact correctly with a range input (slider) in Cypress? - Stack Overflow

programmeradmin4浏览0评论

I'm writing my bachelor thesis about e2e testing in JavaScript although I'm not familiar with testing or JavaScript.

There is range-type input "slider" in the DOM I'm testing:

<input id="sum_slider" 
  class="input-range js-inv-calc-input-sum-range js-input-range" 
  type="range" name="investmentsum" 
  min1="20000" 
  max="150000" 
  value="20000" 
  step="1000" 
  title="Investitionsbetrag" 
  style="background: -webkit-linear-gradient(left, rgb(255, 196, 0) 0%, rgb(255, 196, 0) 0%, rgb(119, 119, 119) 0%) no-repeat;">

The Cypress Documentation suggests this

cy.get('input[type=range]').as('range')
  .invoke('val', 25)
  .trigger('change')

cy.get('@range').siblings('p').should('have.text', '25')

I tried this:

cy.get('#sum_slider[type=range]').as('range')
  .invoke('val', 0%)
  .trigger('change')

I am choosing the percent values because the two last percent values are the only ones that change when using the slider manually.

I'm writing my bachelor thesis about e2e testing in JavaScript although I'm not familiar with testing or JavaScript.

There is range-type input "slider" in the DOM I'm testing:

<input id="sum_slider" 
  class="input-range js-inv-calc-input-sum-range js-input-range" 
  type="range" name="investmentsum" 
  min1="20000" 
  max="150000" 
  value="20000" 
  step="1000" 
  title="Investitionsbetrag" 
  style="background: -webkit-linear-gradient(left, rgb(255, 196, 0) 0%, rgb(255, 196, 0) 0%, rgb(119, 119, 119) 0%) no-repeat;">

The Cypress Documentation suggests this

cy.get('input[type=range]').as('range')
  .invoke('val', 25)
  .trigger('change')

cy.get('@range').siblings('p').should('have.text', '25')

I tried this:

cy.get('#sum_slider[type=range]').as('range')
  .invoke('val', 0%)
  .trigger('change')

I am choosing the percent values because the two last percent values are the only ones that change when using the slider manually.

Share Improve this question edited Nov 4, 2024 at 10:12 Marty Martin 1495 bronze badges asked Mar 6, 2019 at 12:43 user8995745user8995745
Add a ment  | 

3 Answers 3

Reset to default 6

You must set the value to a number not a percent. You should take a look at the element and see what values are valid. Usually there is a min and max attribute on the element.

Notice those attributes on your element

<input id="sum_slider" class="input-range js-inv-calc-input-sum-range js-input-range" type="range" name="investmentsum" min="20000" max="150000" value="20000" step="1000" title="Investitionsbetrag" style="background: -webkit-linear-gradient(left, rgb(255, 196, 0) 0%, rgb(255, 196, 0) 0%, rgb(119, 119, 119) 0%) no-repeat;">

So with your element, the value you set must be between 20000 and 150000. The following should work:

cy.get('input[type=range]')
  .invoke('val', 20001)
  .trigger('change')

Kuceb's answer is still valid, but the example he gives fails because the test must not only obey the min and max range values but also the step must be correct in the test.

Kuceb increments the slider by 1, but the step is 1000.

Run with a value that's an increment of step and the example passes:

cy.get('input[type=range]')
  .invoke('val')
  .should('eq', '20000')

cy.get('input[type=range]')
  .invoke('val', 100_000)

cy.get('input[type=range]')
  .invoke('val')
  .should('eq', '100000')

Note in the current Cypress version 13.15.1 you don't need to trigger a change event.

These are the before and after snapshots of the slider


A custom mand to check min, max, and step

Cypress.Commands.add('range', (selector, value) => {

  const log = Cypress.log({displayName:'range', message: selector})

  if (value) {
    log.set({message: `${log.get('message')} - setting to ${value}`})

    const min = +Cypress.$(selector).attr('min')
    const max = +Cypress.$(selector).attr('max')
    const step = +Cypress.$(selector).attr('step')

    if (min && value < min) {
      throw new RangeError(`Requested value ${value} is below the range minimum ${min}`)
    }
    if (max && value > max) {
      throw new RangeError(`Requested value ${value} is above the range maximum ${max}`)
    }
    if (step && (value % step) !== 0) {
      throw new RangeError(`Requested value ${value} is not a multiple of the range step ${step}`)
    }

    Cypress.$(selector).val(value)
  }

  return Cypress.$(selector).val()
})

Usage

cy.range('input[type=range]')
  .should('eq', '20000')

cy.range('input[type=range]', 100_000)
  .should('eq', '100000')

With a valid value:

With an incorrect test value for the configured step:

Five years later this could not be solved. Here is a work around:

const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
      window.HTMLInputElement.prototype,
      "value"
    ).set
    cy.get('input[type="range"]')
      .then(($range) => {
        // get the DOM node
        const range = $range[0]
        // set the value manually
        nativeInputValueSetter.call(range, 50)
        // now dispatch the event
        range.dispatchEvent(
          new Event("change", { value: 50, bubbles: true })
        )
      })
    cy.wait(2000)
    // assert that the value has been changed
    cy.get("input[type='range']").should("have.value", 50)

What this basically does is that it retrieves the browser's native value setter for the input elements to directly set the slider's value using the native method which bypasses any interference from React's control. It then dispatches a change event to notify the app of the update, ensuring that any event listeners respond to the new value.

Please refer here and join the discussion.

发布评论

评论列表(0)

  1. 暂无评论