2017-05-22 1 views
1

Je suis sûr que c'est un simple mais je n'ai pas pu trouver la cause de cette erreur et encore moins la solution.Objet de localisateur ne peut pas être nul avec Selenium PageObjects

J'utilise des objets page sélénium qui fonctionnaient parfaitement jusqu'à présent lorsque j'ai ajouté une nouvelle page à mes tests.

Voici mon code principal

class RunTest 
{ 

    static IWebDriver driver; 

    [Test] 
    public void Login() 
    { 

     var options = new ChromeOptions(); 

     options.AddArguments("chrome.switches", "--disable-extensions --disable-extensions-file-access-check --disable-extensions-http-throttling --disable-infobars --enable-automation "); 
     options.AddUserProfilePreference("credentials_enable_service", false); 
     options.AddUserProfilePreference("profile.password_manager_enabled", false); 
     driver = new ChromeDriver(options); 

     driver.Url = ConfigurationManager.AppSettings["URL"]; 

     driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10); 

     var loginPage = new LoginPage(driver); 
     loginPage.LoginToApplication("Test1"); 

     IWait<IWebDriver> wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); 
     var element = wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("//*[@id='content']/div/div/div/div/ul/li[4]/div[1]/div[2]/div/button[1]"))); 

     var setenv = new SetEnvironment(driver); 
     setenv.SetEnvQA(); 

    } 

    [Test] 
    public void AddBatchTest() 
    { 
     var AddBatch = new Batch(driver); 
     AddBatch.AddNewBatch("Test1"); 
    } 

    [Test] 
    public void Test1() 
    { 
     var NewCli = new AddNewClient(driver); 
     NewCli.Addanewclient("Test1"); 

Les tests de connexion et Test1 (avec les autres) fonctionne à la perfection mais le test de lot tombe avec

System.ArgumentException: Le SearchContext du l'objet localisateur ne peut pas être nul Nom du paramètre: locator

Le code de la classe de traitement par lots et AddNewClie nt classe sont identiques, donc je ne peux pas voir ce que le problème est

Lot:

namespace OnlineStore.PageObjects 
{ 
    class Batch 
    { 
     IWebDriver driver; 

     //Admin link in left hand otions 
     [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_NavigationPanel_navigationpanel1_hlAdmin']")] 
     public IWebElement AdminScreen { get; set; } 

     //Add new batch link 
     [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_MainBody_HyperLink38']")] 
     public IWebElement AddNewBatchLnk { get; set; } 


     [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_MainBody_DatepickerReceived_txtDate']")] 
     public IWebElement DateReceived { get; set; } 

     [FindsBy(How = How.XPath, Using = "//*[@id='aspnetForm']/div[3]/div/div[2]/div[3]/table[3]/tbody/tr/td/table/tbody/tr[7]/td]")] 
     public IWebElement SelectToday { get; set; } 

     [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_MainBody_txtTotal']")] 
     public IWebElement BatchTotal { get; set; } 

     [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_MainBody_ucCurrency_ddlCurrency']")] 
     public IWebElement Currency { get; set; } 

     [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_MainBody_cboAgency']")] 
     public IWebElement Provider { get; set; } 

     [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_MainBody_txtNote']")] 
     public IWebElement BatchNotes { get; set; } 


     public Batch(IWebDriver driver) 
     { 
      this.driver = driver; 
      PageFactory.InitElements(driver, this); 
     } 

     public void AddNewBatch(string testName) 
     { 
      var userData = ExcelDataAccess.GetTestData(testName); 

      IWait<IWebDriver> wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30.00)); 

      AdminScreen.Click(); 
      wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("//*[@id='ctl00_MainBody_HyperLink38']"))); 

      AddNewBatchLnk.Click(); 
      wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("//*[@id='ctl00_MainBody_DatepickerReceived_txtDate']"))); 

      DateReceived.SendKeys("22/05/2017"); 
      //SelectToday.Click(); 
      BatchTotal.SendKeys("1000"); 
      Currency.SendKeys("USD"); 
      Provider.SendKeys("Client"); 
      BatchNotes.SendKeys("Some Batchg notes here please"); 

     } 
    } 
} 

AddNewClient:

 public AddNewClient(IWebDriver driver) 
    { 
     this.driver = driver; 
     PageFactory.InitElements(driver, this); 
    } 

    public void Addanewclient(string testName) 
    { //Code here 

Toutes les idées? Mise à jour: J'ai essayé de déplacer le code AddBatchTest dans le script de code de connexion et il s'est bien passé, mais quand je l'ai renvoyé à son propre test, il a de nouveau erré.

Trace de pile complète comme demandé dans les commentaires.

Result StackTrace: 
at OpenQA.Selenium.Support.PageObjects.PageFactory.InitElements(Object page, IElementLocator locator, IPageObjectMemberDecorator decorator) 
    at OpenQA.Selenium.Support.PageObjects.PageFactory.InitElements(ISearchContext driver, Object page) 
    at OnlineStore.PageObjects.Batch..ctor(IWebDriver driver) in C:\Users\andrew.logan-smith\documents\visual studio 2015\Projects\OnlineStore\OnlineStore\PageObjects\Batch.cs:line 54 
    at OnlineStore.TestCases.RunTest.AddBatchTest() in C:\Users\andrew.logan-smith\documents\visual studio 2015\Projects\OnlineStore\OnlineStore\TestCases\RunTest.cs:line 52 
Result Message: 
System.ArgumentException : The SearchContext of the locator object cannot be null 
Parameter name: locator 
+0

* Le code dans la classe de traitement par lots et la classe AddNewClient sont identiques, donc je ne vois pas quel est le problème. * Bien, il y a évidemment un problème. Vous devez ajouter la trace complète de la pile ainsi que ** tout ** le code correspondant. – Guy

+0

Je suis d'accord qu'il y a certainement un problème où. J'ai ajouté la trace de la pile. Je crois que j'ai déjà tout le code ** pertinent **. Le reste est juste les éléments et les commandes de sélénium – Smithy7876

+0

'InitElements' a échoué lors de l'initialisation des éléments, les éléments ** sont pertinents **. Et afficher uniquement les signatures de méthodes ne sera probablement jamais utile. – Guy

Répondre

1

L'ordre des Test méthodes RunTest classe est pas nécessairement l'ordre de ecxution. Dans votre cas, la commande est probablement AddBatchTest() ->Login() ->Test1(). Cette cause le driver d'être null lors de l'appel constructeur Batch et PageFactory.InitElements reçoit null comme argument driver-à-dire la SearchContext, d'où l'erreur

Le SearchContext de l'objet de localisation ne peut pas être null

InitElements méthode de github

public static void InitElements(ISearchContext driver, object page) 
{ 
    InitElements(page, new DefaultElementLocator(driver)); 
} 

Je vous suggère de déplacer le Login() sous [SetUp] et d'ajouter [TearDown]. Il se déroulera avant et après chaque test et vous fournir « ardoise propre »

public class RunTest 
{ 
    private IWebDriver driver = null; 

    [SetUp] 
    public void Login() 
    { 
     driver = new ChromeDriver(options); 
     //... 
    } 

    [Test] 
    public void AddBatchTest() 
    { 
     var AddBatch = new Batch(driver); 
     AddBatch.AddNewBatch("Test1"); 
    } 

    [Test] 
    public void Test1() 
    { 
     var NewCli = new AddNewClient(driver); 
     NewCli.Addanewclient("Test1"); 
    } 

    [TearDown] 
    public void TearDown() 
    { 
     if (Driver != null) 
     { 
      Driver.Quit(); 
     } 
    } 
} 

Modifier

Si vous voulez exécuter SetUp et TearDown une fois pour tous les tests que vous pouvez utiliser [TestFixtureSetUp] et [TestFixtureTearDown] annotations.Vous devez également ajouter [TestFixture] à la classe

[TestFixture] 
public class RunTest 
{ 
    [TestFixtureSetUp] 
    public void SetUp() 
    { 
    } 

    [Test] 
    public void AddBatchTest() 
    { 
    } 

    [Test] 
    public void Test1() 
    { 
    } 

    [TestFixtureTearDown] 
    public void TearDown() 
    { 
    } 
} 

* Ceci est pour NUnit 2, pour une utilisation NUnit 3[OneTimeSetUp] et [OneTimeTearDown].

+0

Merci pour cela. Cela fonctionne et résout le problème initial et je suppose que c'est l'approche des meilleures pratiques. De toute façon je peux écrire ceci sans le refaire pour chaque test? Malheureusement, en raison de la façon dont le site est écrit (dont je n'ai aucun contrôle), le script de connexion prend 30 secondes à chaque fois (ses 2 clics et le nom d'utilisateur et mot de passe normal!) le processus énormément. – Smithy7876

+0

@ Smithy7876 J'ai mis à jour ma réponse – Guy

+1

Parfait merci! – Smithy7876