Rayrun
← Back to Discord Forum

Page Object Model and multiple locators with similar names

I have the following ILocators on my POM and wondering if I should be trying to do something smarter to avoid repetition, or if this is acceptable? I would then have 12 methods to click each check box. I am new to Playwright and coding so apologies if this is a stupid question.

private ILocator _chkNmt01 => _reportPage.Locator("label").Filter(new() { HasText = "NMT 01" });
    private ILocator _chkNmt02 => _reportPage.Locator("label").Filter(new() { HasText = "NMT 02" });
    private ILocator _chkNmt03 => _reportPage.Locator("label").Filter(new() { HasText = "NMT 03" });
    private ILocator _chkNmt04 => _reportPage.Locator("label").Filter(new() { HasText = "NMT 04" });
    private ILocator _chkNmt05 => _reportPage.Locator("label").Filter(new() { HasText = "NMT 05" });
    private ILocator _chkNmt06 => _reportPage.Locator("label").Filter(new() { HasText = "NMT 06" });
    private ILocator _chkNmt07 => _reportPage.Locator("label").Filter(new() { HasText = "NMT 07" });
    private ILocator _chkNmt08 => _reportPage.Locator("label").Filter(new() { HasText = "NMT 08" });
    private ILocator _chkNmt09 => _reportPage.Locator("label").Filter(new() { HasText = "NMT 09" });
    private ILocator _chkNmt10 => _reportPage.Locator("label").Filter(new() { HasText = "NMT 10" });
    private ILocator _chkNmt11 => _reportPage.Locator("label").Filter(new() { HasText = "NMT 11" });
    private ILocator _chkNmt12 => _reportPage.Locator("label").Filter(new() { HasText = "NMT 12" });

    public async Task ClickMnt01()
    {
        await _chkNmt01.IsVisibleAsync();
        await _chkNmt01.ClickAsync();
    }

etc....

This thread is trying to answer question "Is there a smarter way to handle multiple locators with similar names in the Page Object Model to avoid repetition?"

7 replies

Perhaps you could have a locator for just label, and then have a function that clicks them based on a parameter, and then use that function in a parameter. I'm not 100% on how it works on .net, but something like this (apologies for syntax errors!):

private ILocator labels = _reportPage.Locator("label");

public async Task ClickNmt(int labelNumber) { 
  labelToClick = labels.Filter( new() { HasText = "NMT " + labelNumber.ToString() } ); 
  labelToClick.IsVisibleAsync();
  labelToClick.ClickAsync();
} 

public async Task ClickAllNmt() {
  for (int i = 0; i < 12; i++) {
    await ClickNmt(i);
  }
}

Perhaps for ClickAllNmt() i < await nmtCount or something like that if it's the amount of labels might change from 12 at some point

In JavaScript you could do i < await labels.count(), or possibly let labelsCount = await labels.count(); before it's needed in the loop

If you want a reason why not to do what you've done, consider what happens if you ever need to change the any of the ClickMntXX functions - now you'll have to change the same thing in at least 12+12 different places. Or you might mistype it at somewhere where you use it. It's also a bit difficult to read and increases the amount of code that one has to check for errors. It can be fine sometimes to repeat code, but in this case the code is very similar, so identifying the similar parts and writing something to handle those similarities is worth it.

The following is more general advice which likely doesn't apply in the code you are asking about.

It might be worth it to have 12 different objects (likely not locators) in memory in some cases, if the overhead of creating a new object was high enough and you needed to use those objects constantly, but I'll assume in this case it's not really an issue. If it was, some kind of array or dictionary containing the objects might be a good solution.

Thank you for taking the time to answer, much appreciated!

You could use a. All() on the label and pass in the filter, this will allow you to simply loop over the labels. Similar to the above example. I can add a snippet but currently AFK

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.