Как выполнить итерацию объекта js и рекурсивно сопоставить его со списком веб-элементов?

#javascript #testing #recursion #cypress

Вопрос:

Допустим, у меня есть этот объект или приспособление, которое я хочу проверить на соответствие существующим данным из DOM:

 export const EXTRAS_MENU_ELEMENTS = [  {  elemName: 'about',  elementExpectedText: 'About',  submenuElements: [  {  elemName: 'version-numbers',  elementExpectedText: 'version numbers'  },  {  elemName: 'terms-of-service',  elementExpectedText: 'terms of service'  },  {  elemName: 'privacy-policy',  elementExpectedText: 'privacy policy'  },  {  elemName: 'vizio-account',  elementExpectedText: 'vizio account'  },  {  elemName: 'license-list',  elementExpectedText: 'license list'  },  {  elemName: 'california-privacy-info',  elementExpectedText: 'california privacy info'  },  {  elemName: 'advertising-privacy-faq',  elementExpectedText: 'advertising amp; privacy faq'  }  ]  },  {  elemName: 'amazon-alexa',  elementExpectedText: 'Amazon Alexa'  },  {  elemName: 'airplay-homekit',  elementExpectedText: 'Apple AirPlay amp; HomeKit Settings'  },  {  elemName: 'apps-and-inputs-row',  elementExpectedText: 'Apps amp; Inputs Row',  submenuElements: [  {  elemName: 'include-hardware-inputs',  elementExpectedText: 'include hardware inputs',  submenuElements: [  {  elemName: 'include-inputs',  elementExpectedText: 'include inputs'  },  {  elemName: 'hide-inputs',  elementExpectedText: 'hide inputs'  }]  },  {  elemName: 'resort-app-icons',  elementExpectedText: 're-sort app icons'  }  ]  },  {  elemName: 'google-assistant',  elementExpectedText: 'Google Assistant'  },  {  elemName: 'watch-and-learn',  elementExpectedText: 'Watch amp; Learn'  } ]  

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

Мой нынешний подход заключается в следующем:

 Cypress.Commands.add('iterateElements', ({ elementLocator, objectArrayData, objectArrayDataTextProp, topDowNavigation = false, expandElements = false, expandElementsLocator, objectArrayChildrenData }) =gt; {  let counter = 0   // Verify that the length of the list is equal to the length of the list of expected elements.  cy.get(elementLocator).should('have.length', objectArrayData.length)  // Get a list of all the settings items and loop through them  cy.get(elementLocator).each((listItem, index) =gt; {  // Match the settings elements from the DOM against the expected elements.  cy.wrap(listItem).should('contain.text', objectArrayData[index][objectArrayDataTextProp])   // If the expand elements is enabled, expand the element.  if (expandElements) {  if (listItem.hasClass(expandElementsLocator)) {  console.log('item has class SETTINGS_EXPAND')  cy.keys('select')  counter    cy.iterateElements({ elementLocator, objectArrayData, objectArrayDataTextProp, topDowNavigation = true, expandElements = true, expandElementsLocator, objectArrayChildrenData })  }  }   // If the top down navigation is enabled, navigate to the next element.  if (topDowNavigation) {  cy.keys('down')  }  }) })  

I use this function to run three different tests:

  • iterate over the extras elements (just to make sure they all exist on the main page)
  • повторите дополнительные элементы, перейдите и сосредоточьтесь на каждом элементе
  • повторите дополнительные элементы, разверните их, если это возможно, перейдите и сосредоточьтесь на каждом элементе.

Дело в том, что значения моей функции при рекурсивном вызове не соответствуют первым, и я понятия не имею, как решить эту проблему сейчас, как получить доступ к каждому дочернему элементу, поскольку имя и уровень родителя меняются по мере того, как я углубляюсь в массив объектов. Кроме того, как мне отслеживать посещенные элементы, чтобы я мог перемещаться по всем узлам.