0

I have a p-dropdown:

HTML:

<span>
  <p-dropdown formControlName="theatreGroup" [options]="theatreGroupsList">
  </p-dropdown>
</span>

TS:

  theatreGroupsList: any[] = [
    { label: 'Hamlet', value: 100 },
    { label: 'Dutchman', value: 351 },
    { label: 'King Lear', value: 180 },
    { label: 'Candida', value: 211 },
    { label: 'Twelfth Night', value: 133 }
  ];

I need to be able to get the theatreGroupsList and select an item. I can do this by checking the value of items in the array:

cy.get('p-dropdown[formControlName="theatreGroup"]').click().contains('Candida').click();

But the problem is theatreGroupsList is dynamic. Therefore, I need to be able to retrieve the list at any time and access its elements using index (i.e. not value or label). Can you help me with this?

  • 1
    You can easily get the options by index, but what do you want to test? Please clarify the question further. –  Jul 21 '21 at 06:02
  • I have already explained in the question. I need to access items by index. For example I should be able to retrieve item with index 3 at any time. – Alpha Bravo Charlie ... Jul 21 '21 at 07:36

2 Answers2

1

I got inspired by Steve Zodiac's comments and KKhan's answer and developed this solution that works for me:

cy.get('p-dropdown[formControlName="theatreGroup"]').click().then(x => {
  cy.get('p-dropdown[formControlName="theatreGroup"]>div>div>div>ul>p-dropdownitem').then(groups => {
    
    // Assume we need to access item at index 3, then select in the dropdown
    let group3 = groups[3]['innerText'];        

    // An extra click to prevent error about detached element from the DOM.
    cy.get('p-dropdown[formControlName="theatreGroup"]').click();

    cy.get('p-dropdown[formControlName="theatreGroup"]').click().get('div').contains(group3).click();
  });
});
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
0

I'm a little unsure of your test goal, but with dynamic text it pays to assert that the list has items before testing.

Here's some ideas

cy.get('p-dropdown[formControlName="theatreGroup"]').click() //open

cy.get('ul.p-dropdown-items li span')    
  .should('have.length', 'gt', 0);     // list is animated on open, 
                                       // so wait for a populated list 

cy.get('ul.p-dropdown-items li span')  
  .then(($items, index) => {
    const texts = [...$items].map(item => item.innerText)
    ...  // take a look at the texts

cy.get('ul.p-dropdown-items li span')  
  .eq(1)
  .should('have.text', 'Candida')
  • The purpose of the test is retrieving array items by index (not label or value). Thus, your solution did not help me. Also: 1) There exists no class names 'p-dropdown-items'. 2) Wrong pramateres are sent to 'then'. 'then' takes either a callback function or an array of options and a callback function. ... Thanks for your effort :-) – Alpha Bravo Charlie ... Jul 20 '21 at 13:03
  • ABC - the HTML you show is the source code, not HTML that Cypress sees. The runtime PrimeNG page ***does*** actually have `.p-dropdown-items` class names which can be used to get the options. –  Jul 21 '21 at 06:00