2016-05-25 19 views
1

Angesichts des Seitenobjektmodell-Entwurfsmusters in Selenium muss ich prüfen, ob das WebElement auf der Seite vorhanden/aktiviert/klickbar ist, bevor eine Aktion ausgeführt wird.Wie bekomme ich FindsByAttribute von IWebElement in C# Selen? [Seitenobjektmodell]

Die Basis 'Seite' Klasse:

public class Page 
{    
    public Page() 
    { 
     PageFactory.InitElements(SeleniumTests.driver, this); 
    } 
} 

Eine vererbte Klasse:

class Page_Certificate_ChooseOperator : Page 
    {    
     [FindsBy(How = How.Id, Using = "SearchOperatorName")] 
     public IWebElement txtName { get; set; } 

     [FindsBy(How = How.Id, Using = "SearchOperatorEstablishmentNumber")] 
     public IWebElement txtEstablishmentNumber { get; set; } 

     [FindsBy(How = How.Id, Using = "searchButton")] 
     public IWebElement btnSearch { get; set; } 

     public void SelectOperator(String name, String establishmentNumber) 
     { 
      this.txtName.SetInputField(name); 
      this.txtEstablishmentNumber.SetInputField(establishmentNumber);     
      this.btnSearch.SafeClick(); 
     }   
    } 

Schließlich wird die Klasse für die Erweiterungsmethoden:

public static class SeleniumExtensionMethod 
    { 
     public static void SetInputField(this IWebElement webElement, String value) 
     { 
      webElement.Clear(); 
      webElement.SendKeys(value); 
     }  

     public static void SafeClick(this IWebElement webElement, int timeout_in_seconds) 
     {  
      //This is the difficult part. I need to check if the webElement is visible, but I don't want to write "low-level" code and specify the ID and selector. Is there a way I can find out how the webElement was created by this class and say something like "webElement.How" to find "How.ID" or "webElement.Using" to find "btnSearch"? I need to use something like the below code using the PageObject 
      // WebDriverWait wait = new WebDriverWait(SeleniumTests.driver, TimeSpan.FromSeconds(10)); 
      // IWebElement dynamicElement = wait.Until<IWebElement>(driver => driver.FindElement(By.Id("btnSearch"))); 
      // dynamicElement.Click(); 

      //Now, I just use this, but it crashes on NoSuchElementFound since it goes too fast. I don't want to use ImplicitWait. 
      btnSearch.Click(); 


     } 
    } 

Die Herausforderung, die ich bin vor ist, dass ich eine ExplicitWaity benötige, bevor ich auf die Schaltfläche btnSearch klicke, da sie ein NoSuchElem auslöst entFoundException. Da ich das [FindsBy] -Attribut verwende, denke ich, sollte es eine Möglichkeit geben zu überprüfen, wie das WebElement gefunden/erstellt wurde? Wie kann ich das machen? Oder wie kann ich sauberen Code haben und ExplicitWait für ein Page Object verwenden?

Antwort

1

So warten Sie auf ein Element vorhanden/aktiviert/anklickbar sein, können Sie einen Kellner mit dem ElementToBeClickable Zustand verwenden können:

[FindsBy(How = How.Id, Using = "searchButton")] 
public IWebElement btnSearch { get; set; } 

public void SelectOperator(String name, String establishmentNumber) 
{ 
    this.txtName.SetInputField(name); 
    this.txtEstablishmentNumber.SetInputField(establishmentNumber);     

    new WebDriverWait(SeleniumTests.driver, TimeSpan.FromSeconds(10)) 
     .Until(ExpectedConditions.ElementToBeClickable(this.btnSearch)) 
     .Click(); 
} 
+0

Das funktioniert occassionally, sondern wirft auch manchmal ein TargetInvocationException in WebDriver.Support.dll aufgetreten . Weißt du, wie das zu beheben ist? Es ist sehr wichtig für den Erfolg unseres Projekts. Vielen Dank! –

+0

Was ist die innere Ausnahme? Sie sollten eine neue Frage erstellen, es scheint ein anderes Problem zu sein. –