Rayrun
← Back to Discord Forum

How to iterate though a list of css locators?

Hello,

How can I iterate through a list of locators? all() is not available and I am getting flagsBtn is not a iterable

const flagsBtn = page.locator('mat-button-toggle');                                                             
        for (const [el, index] of flagsBtn) {                                                                                                                                                             
          if (index !== 0) {                                                                                                                                                  
            await el.click();                                                                                                                                                                             
          }                                                                                                                                                                   
        }                                                                                                                                                                                                 
        await expect(checkboxes).toHaveCount(13);                                                                                                                             
      });

This thread is trying to answer question "How can one iterate through a list of CSS locators in Playwright when 'all()' is not working as expected?"

25 replies

why all() is not available?

I was wondering the same thing

anyhow, I'd probably use const count = await page.locator('mat-button-toggle').count() and then do for loop and use page.locator('mat-button-toggle').nth(...) to click

but using all() would be simpler

that is a great idea, thank you. I wish I knew why all() doesn't work.

This is not working... see anything wrong, please? The icon buttons are not getting clicked

it.only('should have records', async ({ page }) => {                                                                                                                   
        const flagsBtn = page.locator('mat-button-toggle').count();                                                                                                          
        for (index in flagsBtn) {                                                                                                                                            
          if (index !== 0) {                                                                                                                                                 
            await page.locator('mat-button-toggle').nth(index).click();
          }
        }                                                                                                                                                                    
        await page.waitForTimeout(900000)                                                                                     
      });         ```

page.locator('mat-button-toggle').count();

missing await

abdomdata_41602

Make sure that all page.locator('mat-button-toggle') objects are visible when you are using the count() method. The software doesn't know how many elements should be available.

shouldn't page.locator('mat-button-toggle').count(); wait for them to be available?

it won't

to be fair, all() does not wait for elements to be visible either, both count and all returns immediatelly what is present at that time

ok, thanks

Will const btns = page.getByTestId('flag-btn'); wait for elements?

I have the below, but I am getting btns is not a iterable

it.only('should have records', async ({ page }) => {                                                                                                     
        const btns = page.getByTestId('flag-btn').all();                                                                                                     
        for (const btn of btns) {                                                                                                                            
          await btn.click();                                                                                                                                 
        }                                                                                                                                                    
      });

it is for the html

<mat-button-toggle _ngcontent-ng-c2732246807="" role="presentation" data-testid="flag-btn" class="mat-button-toggle ng-tns-c2732246807-5 mat-button-toggle-standalone mat-button-toggle-appearance-standard" ng-reflect-checked="false" ng-reflect-value="[object Object]" id="mat-button-toggle-1"><button type="button" class="mat-button-toggle-button mat-focus-indicator" id="mat-button-toggle-1-button" tabindex="0" aria-pressed="false"><span class="mat-button-toggle-label-content"><mat-icon _ngcontent-ng-c2732246807="" role="img" class="mat-icon notranslate material-icons mat-ligature-font mat-icon-no-color" aria-hidden="true" data-mat-icon-type="font">flag</mat-icon></span></button><span class="mat-button-toggle-focus-overlay"></span><span matripple="" class="mat-ripple mat-button-toggle-ripple" ng-reflect-trigger="[object HTMLButtonElement]"></span></mat-button-toggle>

Will const btns = page.getByTestId('flag-btn'); wait for elements?

it will not

I have the below waitfortimeout so the elements are ready but I still am not able to grab them.

it.only('should have records', async ({ page }) => {                                                                                                              
        await page.waitForTimeout(1000)                                                                                       
        const btns = page.getByTestId('flag-btn').all();                                                                                                     
        for (const btn of btns) {                                                                                                                            
          await btn.click();                                                                                                                                 
        }                                                                                                                                                    
      });

page.getByTestId('flag-btn').all();

missing await

dirvinautomation_16636

all was added in v1.29. Maybe upgrade versions?

using 1.38 version

I get TypeError: .for is not iterable. any ideas why, please?

beforeEach(async ({ page }) => {                                                                                                                                  
          await page.waitForTimeout(2000)                                                                                               
          const btns = await page.getByTestId('flag-btn').all();                                                                                               
          for (let [btn, index] of btns) {                                                                                                      
            console.log(index);                                                                                                                 
            if (index > 0) {                                                                                                                    
              await btn.click();                                                                                                                
            }                                                                                                                                                  
          }                                                                                                                                     
        });

maybe it returns empty array?

refactoreric

Is the destructuring to blame? I think each element of btns is not an array, but the code [btn, index] of btns is treating them like arrays.

The example from the playwright.dev website for iterating through all elements is also different:

for (const row of await page.getByRole('listitem').all())
  console.log(await row.textContent());
nico_olivares
nico_olivares

100% the deconstructing. btns is an array of locators. You can't deconstruct [btn, index] out of it. If you want the index you would be better off using

for (let i = 0; i < btns.lenght(); i++) { }

Related Discord Threads

TwitterGitHubLinkedIn
AboutQuestionsDiscord ForumBrowser ExtensionTagsQA Jobs

Rayrun is a community for QA engineers. I am constantly looking for new ways to add value to people learning Playwright and other browser automation frameworks. If you have feedback, email luc@ray.run.