在selenium C#WebDriver中管理框架

在selenium C#WebDriver中管理框架,c#,selenium-webdriver,C#,Selenium Webdriver,需要了解在框架内处理元素的一些更好的实践。Selenium WebDriver仅在框架/主文档的上下文中工作。在IIWebDriver.SwitchTo()启动之前,它无法找到其他帧的元素 痛苦的是我经常不得不在不同的画面之间切换。在任何时候我都不能相信IWebDriver当前在哪个帧上 我可以在一个浏览器实例中有多个IWebDriver实例(克隆或其他),还是每个浏览器实例只有一个?我想我可以将IWebDriver属性切换到特定的帧,我可以相信我会在那里找到元素。对于其他类,我会在不同的帧上使

需要了解在框架内处理元素的一些更好的实践。Selenium WebDriver仅在框架/主文档的上下文中工作。在I
IWebDriver.SwitchTo()启动之前,它无法找到其他帧的元素

痛苦的是我经常不得不在不同的画面之间切换。在任何时候我都不能相信IWebDriver当前在哪个帧上

我可以在一个浏览器实例中有多个IWebDriver实例(克隆或其他),还是每个浏览器实例只有一个?我想我可以将
IWebDriver
属性切换到特定的帧,我可以相信我会在那里找到元素。对于其他类,我会在不同的帧上使用
IWebDriver
属性

此外,当使用
PageFactory.InitElements
构造页面对象时,应该如何处理框架?在找到元素之前,我必须将IWebDriver切换到正确的帧。但是我的页面对象类会一直工作吗,不管我以后切换到哪个框架?例如,给定两个来自不同框架的页面对象-我可以在测试中无缝地使用它们而不考虑框架吗


找不到任何关于框架管理的最佳实践。

如果WebDriver中的iframe支持更强大一点,那就更好了,但是有一些方法可以帮助解决这种情况。在回答您关于WebDriver是否会在测试中无缝处理iframe切换的问题时,它不会。即使在PageFactory针对page对象运行之后,您也需要根据需要自行管理该切换

一个值得考虑的选项是创建一些实用方法来处理iframe的切换

这意味着您可以在访问元素之前调用iframe切换方法,并让PageFactory找到它。该逻辑可以在页面对象中,因此测试编写器不需要在测试中处理iframe切换。从测试中抽象出这种复杂程度将有助于他们专注于业务案例。它还将有助于维护,因为涉及这些iFrame的产品更改可以在Page对象中更改,然后使用Page对象的所有测试都不需要更改(关于框架)

例如:

public class MyPageObject
    {
        private readonly IWebDriver _driver;

        [FindsBy(How = How.Id, Using = "id")]
        private IWebElement _myWebElementInIFrame;

        public MyPageObject(IWebDriver webDriver)
        {
            PageFactory.InitElements(webDriver, this);
            _driver = webDriver;
        }

        public void DoStuff()
        {
            SwitchToIframe("myiframe");
            _myWebElementInIFrame.Click(); //element found using PageFactory data now
            SwitchToDefaultContent();
        }

        public void SwitchToIframe(string frameName)
        {
            _driver.SwitchTo().Frame(frameName);
        }

        public void SwitchToDefaultContent()
        {
            _driver.SwitchTo().DefaultContent();
        }
    }
您可以使用一些方法模板来进一步了解这一点:

public class MyPageObject : BasePageObject
    {

        [FindsBy(How = How.Id, Using = "id")]
        private IWebElement _myWebElementInIFrame;

        public MyPageObject(IWebDriver webDriver)
            : base(webDriver)
        {
            PageFactory.InitElements(webDriver, this);
        }

        public void DoStuff()
        {
            ExecuteActionInIFrame(() =>
            {
                _myWebElementInIFrame.Click(); //element found using PageFactory data now
            }, "myiframe", "mynestediframe");
        }
    }

    public abstract class BasePageObject
    {
        protected IWebDriver WebDriver { get; }

        protected BasePageObject(IWebDriver webDriver)
        {
            WebDriver = webDriver;
        }

        public void ExecuteActionInIFrame(Action action, params string[] frameNames)
        {
            foreach (string frameName in frameNames)
            {
                WebDriver.SwitchTo().Frame(frameName); //switch into multiple nested iframes in passed in order
            }

            //perform action now that we're in proper iframe
            action();

            //bounce out to root to have a standard starting point for next action
            WebDriver.SwitchTo().DefaultContent();
        }
    }
另一个帮助我的技巧是,您可以通过一些javascript获取当前iframe的名称。如果需要此类信息,在遍历iframe时,这可能有助于确定您在整个DOM中的确切位置


希望这有帮助。

好的,谢谢回复。我怀疑我必须对我的类进行建模,以便不依赖于我是哪一帧,而是始终进行适当的切换。