cypress-plugin-tab icon indicating copy to clipboard operation
cypress-plugin-tab copied to clipboard

cy.tab doesn't properly log

Open NicholasBoll opened this issue 5 years ago • 1 comments

I noticed while using this plugin that a Cypress Command log only happened in certain instances. It only creates Command Log entries when the tab event isn't cancelled. In my case, I'm using a focus trap and the library often cancels the event.

Logging happens implicitly here:https://github.com/Bkucera/cypress-plugin-tab/blob/8e74c21b084fe83fc8c036a879694be0f83481b5/src/index.js#L60 which runs https://github.com/cypress-io/cypress/blob/6ed8d31cf045acd486757474934ef84f5f96cb74/packages/driver/src/cy/commands/actions/focus.coffee#L11 which does contain a Cypress.log.

Playing around a bit, I commented out the cy.now('focus', cy.$$(newEl)) and instead did:

return cy.$$(newElm).focus();

With that change, all logging goes away. To bring it back (always), we can add explicit logging:

const log = Cypress.log({
  $el: cy.$$(subject || win.document.activeElement),
  consoleProps: () => {
    'Applied To': Array.from(subject), // convert jQuery nodeList to normal array for logging
    // additional props can go here
  }
})

// get a "before" snapshot
log.snapshot('before', { next: 'after' });

// this replaces the return of this command:
  return new Promise((resolve) => {
    doc.defaultView.requestAnimationFrame(resolve)
  }).then(() => {
  // return Promise.try(() => {
    return keydown(activeElement, options, simulatedDefault, () => cy.$$(doc.activeElement))
  }).then((el) => {
    // Set the new element and finalize the snapshot
    log.set('$el', el).snapshot();
    return el;
  }).finally(() => {
    keyup(activeElement, options)
    log.end()
  })

I also added the cy.$$(doc.activeElement) because a non-jQuery-wrapped subject was being returned which cause problems in certain cases.

Cypress does some magic and I can't remember if a log automatically happens on error or not. I don't have a log.snapshot() on failure explicitly here, but there is one on success. There will be a Cypress DOM snapshot before and after the tab key was pressed, which should show any DOM diffs of any focus or blur handlers applied to the elements. Also the before snapshot will have the element that previously had focus and the after snapshot will have the element that focus went to.

I could make a PR with this change, for now I'm wrapping for this logging.

Right now I'm using the following to add this functionality:

Cypress.Commands.overwrite('tab', (originalFn, subject) => {
  const prevSubject = cy.$$(subject || cy.state('window').document.activeElement);

  const log = Cypress.log({
    $el: prevSubject,
    consoleProps() {
      return {
        'Applied To': prevSubject.toArray()[0],
      };
    },
  });

  log.snapshot('before', {next: 'after'});

  return Cypress.Promise.try(() => originalFn(subject))
    .then(value => {
      log.set('$el', value).snapshot();
      return value;
    })
    .finally(() => {
      log.end();
    });
});

NicholasBoll avatar Dec 04 '19 23:12 NicholasBoll

awesome @NicholasBoll, I'll gladly accept a PR for this. feel free to put up what you got and I can add the tests

kuceb avatar Dec 05 '19 19:12 kuceb