Cypress клик / триггер не вызывает eventListeners - PullRequest
0 голосов
/ 08 октября 2019

В течение последних нескольких месяцев я разрабатывал моделировщик рабочих процессов для заключительного этапа моего обучения в области знаний о СЭ. Я использовал mxGraph и ванильный javascript, и я попытался настроить некоторые базовые тесты E2E с помощью Cypress.

Я столкнулся с некоторыми проблемами при (я предполагаю) срабатывании прослушивателей событий. Некоторые кнопки реагируют на нажатие / срабатывание кипариса, а некоторые - НЕ. Ни одна из кнопок в моем приложении не имеет действий onClick или какого-либо другого атрибута, который содержит метод модели или контроллера. Вместо этого все кнопки и клавиши имеют обработчики и слушатели, созданные утилитарным классом mxGraph-editor.

Я пытался воссоздать некоторые действия, используя те же тесты E2E на общедоступных примерах mxGraph (см. Код кипариса). Перетаскивание объекта (из меню на холст (# 1) и с холста на холст (# 4)) и выбор объекта (# 2), к сожалению, не работают.

Двойной щелчок на объекте и изменение текста (# 3) работает, однако ... и я заблудился. Я пробовал все разные способы форсирования, ожидания, нажатия и запуска, но все безрезультатно.

describe('mxGraph "ports" example', function () {

    it('Start ports example', function () {
        cy.visit('https://jgraph.github.io/mxgraph/javascript/examples/ports.html')
        cy.wait(500)
    })
    // Example #1 : FAIL
    it('#1 Create new object by dragging', function () {
        cy.get('div[id="sidebarContainer"]').find('img[title="Drag this to the diagram to create a new vertex"]').first()
           .trigger('mousedown', { force: true})
            .trigger('mousemove', { clientX: 250, clientY: 250, force: true})
            .trigger('mouseup', {force: true})
        cy.get('div[id="graphContainer"]').find('svg').trigger('drop', { force: true })
        cy.wait(500)
    })
})
describe('mxGraph "user object" example', function () {

    it('Start userobject example', function () {
        cy.visit('https://jgraph.github.io/mxgraph/javascript/examples/userobject.html')
        cy.wait(500)
    })
    // Example #2 : FAIL
    it('#2 Single click on object (green highlight should appear)', function () {
        cy.get('rect').first().click({ force: true })
        cy.wait(500)
    })
    // Example #3 : PASS
    it('#3 Double click & edit object (Text should be modified)', function () {
        cy.get('rect').first().dblclick({ force: true })
        cy.wait(500)
        cy.get('div [class="mxCellEditor mxPlainTextEditor"]').first().type('text modified')
        cy.wait(500)
    })
    // Example #4 : FAIL
    it('#4 Drags object to center of canvas (Object should be moved)', function () {
        cy.get('rect').first()
            .trigger('mousedown', { force: true})
            .trigger('mousemove', { clientX: 250, clientY: 250, force: true})
            .trigger('mouseup', {force: true})
        cy.wait(500)
    })
})

Любая помощь с благодарностью. Заранее спасибо!

1 Ответ

0 голосов
/ 09 октября 2019

Похоже, что ваше приложение использует события указателя, поэтому попробуйте заменить mouse на pointer во всех этих именах событий.

Кроме того, вот более полная абстракция вокруг перетаскивания:


const dragTo = (subject, to, opts) => {

  opts = Cypress._.defaults(opts, {
    // delay inbetween steps
    delay: 0,
    // interpolation between coords
    steps: 0,
    // >=10 steps
    smooth: false,
  })

  if (opts.smooth) {
    opts.steps = Math.max(opts.steps, 10)
  }

  const win = subject[0].ownerDocument.defaultView

  const elFromCoords = (coords) => win.document.elementFromPoint(coords.x, coords.y)
  const winMouseEvent = win.MouseEvent

  const send = (type, coords, el) => {

    el = el || elFromCoords(coords)

    if (type.includes('drag') || type === 'drop') {
      return el.dispatchEvent(
        new Event(type, Object.assign({}, { clientX: coords.x, clientY: coords.y }, { bubbles: true, cancelable: true }))
      )
    }

    el.dispatchEvent(
      new winMouseEvent(type, Object.assign({}, { clientX: coords.x, clientY: coords.y }, { bubbles: true, cancelable: true }))
    )
  }

  const toSel = to

  function drag (from, to, steps = 1) {

    const fromEl = elFromCoords(from)

    const _log = Cypress.log({
      $el: fromEl,
      name: 'drag to',
      message: toSel,
    })

    _log.snapshot('before', { next: 'after', at: 0 })

    _log.set({ coords: to })

    send('mouseover', from, fromEl)
    send('pointerover', from, fromEl)
    send('mousedown', from, fromEl)
    send('pointerdown', from, fromEl)
    send('dragstart', from, fromEl)

    cy.then(() => {
      return Cypress.Promise.try(() => {

        if (steps > 0) {

          const dx = (to.x - from.x) / steps
          const dy = (to.y - from.y) / steps

          return Cypress.Promise.map(Array(steps).fill(), (v, i) => {
            i = steps - 1 - i

            let _to = {
              x: from.x + dx * (i),
              y: from.y + dy * (i),
            }

            send('mousemove', _to, fromEl)

            return Cypress.Promise.delay(opts.delay)

          }, { concurrency: 1 })
        }
      })
      .then(() => {

        send('mousemove', to, fromEl)
        send('pointermove', to, fromEl)
        send('drag', to, fromEl)
        send('mouseover', to)
        send('pointerover', to)
        send('dragover', to)
        send('mousemove', to)
        send('pointermove', to)
        send('drag', to)
        send('mouseup', to)
        send('pointerup', to)
        send('dragend', to)
        send('drop', to)

        _log.snapshot('after', { at: 1 }).end()

      })

    })

  }

  const $el = subject
  const fromCoords = getCoords($el)
  const toCoords = getCoords(cy.$$(to))

  drag(fromCoords, toCoords, opts.steps)
}

const getCoords = ($el) => {
  const domRect = $el[0].getBoundingClientRect()
  const coords = { x: domRect.left + (domRect.width / 2 || 0), y: domRect.top + (domRect.height / 2 || 0) }

  return coords
}

Cypress.Commands.addAll(
  { prevSubject: 'element' },
  {
    dragTo,
  }
)

Вот как бы вы его использовали:

describe('mxGraph "ports" example', function () {
  beforeEach(() => {
    cy.visit('https://jgraph.github.io/mxgraph/javascript/examples/ports.html')
    cy.get('div#splash').should('not.be.visible')
  })

  // Example #1 : FAIL
  it('#1 Create new object by dragging', function () {
    cy.get('div[id="sidebarContainer"]').find('img[title="Drag this to the diagram to create a new vertex"]').first()
    .dragTo('div[id="graphContainer"]')
  })
})
...