0

I'm new-ish to C# and SO, please let me know if I can improve anything.

We're following the page object model and I have a page that I need to use inside and out of an iframe.

It looks like this at the moment:

public class MyPage {
    protected IPage Page;

    public MyPage (IPage page) {
        Page = page;
    }

    public ILocator MyButton => Page.Locator("#myButton");
}

public class MyPageIframe {
    protected IFrameLocator MyIframe;

    public MyPageIframe (IPage page) {
        MyIframe = page.FrameLocator("#myIframe");
    }

    public MyButton => MyIframe.Locator("#myButton");
}

The locators for both are exactly the same, except the context the Locator() method is called on. Is there a way to make these the same class, with one MyButton that works with or without the iframe?

In my head, the magic solution would be something like this:

public class MyPage {
    // where someType can be either IPage or IFrameLocator
    protected someType context;

    public MyPage(IPage page, IFrameLocator locator) {
        // do something to set context?
    }

    public MyButton => context.Locator("#myButton");
}
Bentimus
  • 13
  • 4

1 Answers1

0

The first solution that came to my mind for your problem is this:

using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync();
var page = await browser.NewPageAsync();

var home = new HomePage(page);
ILocator myButton = home.MyButton;
ILocator myOtherButton = home.MyOtherButton;

public abstract class BasePage
{
    protected BasePage(IPage page)
    {
        Page = page;
    }

    protected IPage Page { get; }

    public virtual ILocator Locate(string frameLocator, string locator) => Page.FrameLocator(frameLocator).Locator(locator);

    public virtual ILocator Locate(string locator) => Page.Locator(locator);
}

public class HomePage : BasePage
{
    public HomePage(IPage page)
        : base(page)
    {
    }

    public ILocator MyButton => Locate("#myButton");
    public ILocator MyOtherButton => Locate("#myIframe", "#myOtherButton");
}
ggeorge
  • 1,496
  • 2
  • 13
  • 19