Es wäre schön, wenn Iframe-Unterstützung in WebDriver ein wenig robuster wäre, aber es gibt Möglichkeiten, um die Situation zu helfen. Als Antwort auf Ihre Frage, ob WebDriver in Ihren Tests die iFrame-Umschaltung nahtlos umsetzt, wird es nicht funktionieren. Sie müssen diese Umstellung nach Bedarf selbst dann verwalten, wenn PageFactory für das Seitenobjekt ausgeführt wurde.
Eine Option, die eine Überlegung wert sein könnte, ist die Erstellung einiger Hilfsmethoden, die das Ein- und Ausblenden von Iframes handhaben.
Dies bedeutet, dass Sie vor dem Zugriff auf das Element in Ihre iframe-Switching-Methode wechseln können und von der PageFactory gefunden werden. Diese Logik kann im Page Object enthalten sein, sodass der Testschreiber bei Tests keine Iframe-Umschaltung durchführen muss. Wenn Sie diese Komplexität aus den Tests abstrahieren, können Sie sich auf die Geschäftsfälle konzentrieren. Es hilft auch bei der Wartung, da Produktänderungen, die diese Iframes betreffen, nur im Page Object geändert werden können und dann alle Tests, die das Page Object verbrauchen, nicht geändert werden müssen (in Bezug auf Frames).
Ein Beispiel:
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();
}
}
Sie könnten ein bisschen weiter eine Methode Templating mit nehmen dies:
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();
}
}
Noch ein Tipp, der mir half, war der Name eines aktuellen iframe über einige bekommen Javascript. Dies kann Ihnen helfen zu bestimmen, wo genau Sie sich im gesamten DOM befinden, während Sie Iframes durchlaufen, wenn Sie diese Art von Informationen benötigen.
Hoffe, das hilft.
Okay, danke für die Antwort. Ich vermutete, dass ich meine Klassen so modellieren muss, dass ich nicht darauf angewiesen bin, in welchem Rahmen ich bin, sondern dass ich immer richtig switche. –