Playwright C#:如何将iframe内外元素定位合并为同一类?
合并iframe内外操作的页面对象类
我是C#和Stack Overflow的新手,若有需要改进之处请告知。我们采用页面对象模型,当前有一个页面需要在iframe内外操作,现有代码分为两个类:
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 ILocator MyButton => MyIframe.Locator("#myButton"); }
两者的定位器完全相同,仅调用Locator()方法的上下文不同。是否可以将它们合并为同一个类,使单个MyButton能同时适用于iframe内外?我期望的理想实现如下:
public class MyPage { // someType可以是IPage或IFrameLocator protected someType context; public MyPage(IPage page, IFrameLocator locator) { // 设置context的逻辑 } public ILocator MyButton => context.Locator("#myButton"); }
解决方案
核心思路是通过适配器模式为IPage和IFrameLocator创建统一的行为抽象,让两个类型可以共用同一套元素定位逻辑:
- 定义统一的上下文接口,封装
Locator方法
public interface ILocatorContext { ILocator Locator(string selector); }
- 修改
MyPage类,通过内部适配器类适配两种上下文,并提供对应的构造函数
public class MyPage { protected readonly ILocatorContext _context; // 针对页面上下文(非iframe)的构造函数 public MyPage(IPage page) { _context = new PageLocatorContext(page); } // 针对iframe上下文的构造函数 public MyPage(IFrameLocator iframeLocator) { _context = new IframeLocatorContext(iframeLocator); } // 共用的元素定位逻辑 public ILocator MyButton => _context.Locator("#myButton"); // 内部适配器:适配IPage private class PageLocatorContext : ILocatorContext { private readonly IPage _page; public PageLocatorContext(IPage page) => _page = page; public ILocator Locator(string selector) => _page.Locator(selector); } // 内部适配器:适配IFrameLocator private class IframeLocatorContext : ILocatorContext { private readonly IFrameLocator _iframeLocator; public IframeLocatorContext(IFrameLocator iframeLocator) => _iframeLocator = iframeLocator; public ILocator Locator(string selector) => _iframeLocator.Locator(selector); } }
使用方式
- 操作页面(非iframe)内元素:
var page = new MyPage(playwrightPage); page.MyButton.ClickAsync();
- 操作iframe内元素:
var iframeContext = playwrightPage.FrameLocator("#myIframe"); var iframePage = new MyPage(iframeContext); iframePage.MyButton.ClickAsync();
这种实现既消除了代码冗余,又保留了页面对象模型的封装性,后续新增元素时只需在MyPage类中添加对应的ILocator属性即可,无需重复编写定位逻辑。
内容的提问来源于stack exchange,提问作者Bentimus
相关产品推荐
相关产品推荐

