UNPKG

cypress-plugin-tab

Version:

<div align="center"> <!-- <img src="docs/readme-logo.png"> --> <h1>cypress-plugin-tab <kbd>beta</kbd></h1> <a href="https://www.npmjs.com/package/cypress-plugin-tab"><img src="https://img.shields.io/npm/v/cypress-plugin-tab.svg?style=flat"></a

148 lines (106 loc) 3.09 kB
const tabSequence = require('ally.js/query/tabsequence') const { _, Promise } = Cypress Cypress.Commands.add('tab', { prevSubject: ['optional', 'element'] }, (subject, opts = {}) => { const options = _.defaults({}, opts, { shift: false, }) debug('subject:', subject) if (subject) { return performTab(subject[0], options) } const win = cy.state('window') const activeElement = win.document.activeElement return performTab(activeElement, options) }) const performTab = (el, options) => { const doc = el.ownerDocument const activeElement = doc.activeElement const seq = tabSequence({ strategy: 'quick', includeContext: false, includeOnlyTabbable: true, context: doc.documentElement, }) let index = seq.indexOf(el) if (index === -1) { if (el && !(el === doc.body)) { pluginError(` Subject is not a tabbable element - Use cy.get(\'body\').tab() if you wish to tab into the first element on the page - Use cy.focused().tab() if you wish to tab into the currently active element `) } } debug(seq, index) /** * @type {HTMLElement} */ const newElm = nextItemFromIndex(index, seq, options.shift) const simulatedDefault = () => { if (newElm.select) { newElm.select() } return cy.now('focus', cy.$$(newElm)) // newElm.focus() // return newElm } return new Promise((resolve) => { doc.defaultView.requestAnimationFrame(resolve) }).then(() => { // return Promise.try(() => { return keydown(activeElement, options, simulatedDefault, () => doc.activeElement) }).finally(() => { keyup(activeElement, options) }) } const nextItemFromIndex = (i, seq, reverse) => { if (reverse) { const nextIndex = i <= 0 ? seq.length - 1 : i - 1 return seq[nextIndex] } const nextIndex = i === seq.length - 1 ? 0 : i + 1 return seq[nextIndex] } const tabKeyEventPartial = { key: 'Tab', code: 'Tab', keyCode: 9, which: 9, charCode: 0, } const fireKeyEvent = (type, el, eventOptionsExtend, bubbles = false, cancelable = false) => { const win = el.ownerDocument.defaultView const eventInit = _.extend({ bubbles, cancelable, altKey: false, ctrlKey: false, metaKey: false, shiftKey: false, }, eventOptionsExtend) const keyboardEvent = new win.KeyboardEvent(type, eventInit) const cancelled = !el.dispatchEvent(keyboardEvent) return cancelled } const keydown = (el, options, onSucceed, onCancel) => { const eventOptions = _.extend({}, tabKeyEventPartial, { shiftKey: options.shift, }) const cancelled = fireKeyEvent('keydown', el, eventOptions, true, true) if (cancelled) { return onCancel() } return onSucceed() } const keyup = (el, options) => { const eventOptions = _.extend({}, tabKeyEventPartial, { shiftKey: options.shift, }) return fireKeyEvent('keyup', el, eventOptions, true, false) } const pluginError = (mes) => { throw new Error(`[cypress-plugin-tab]: ${mes}`) } const debug = function () { // console.log(...arguments) }