2014-11-04 2 views
3

У меня есть веб-страницы в веб-проекте «CalculatorWeb», где я поместил одно текстовое поле с идентификатором «txtNum1»исключение «нет такого элемента» при использовании Selenium с C#

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title></title> 
</head> 
<body> 
    <form id="frmCalc"> 
     <div style="padding-top:20px;"> 
      My Sample Text Box <br/><br/> 
      <input id="txtNum1" type="text" /> 
     </div> 
    </form> 
</body> 
</html> 

Ничего фантазии так страницы загружает как ниже

Web Page Preview

Теперь я создал полнометражный файл «BrowserTest1.feature» в мой проект «Calculator.Specs». Код следующего

Feature: BrowserTest1 
In order to check url 
As browser 
I want to be see url of page 

@mytag 
Scenario: Go to URL 
    Given I have entered 'http://localhost:58529/' 
    When I go to that url 
    Then there is a text box on the page with id 'txtNum1' 

Я тогда свой код файл BrowserTest.cs для реализации модульных тестов

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using OpenQA.Selenium; 
using OpenQA.Selenium.Chrome; 
using OpenQA.Selenium.Support.UI; 
using TechTalk.SpecFlow; 

namespace Calculator.Specs 
{ 
    [Binding] 
    class BrowserTest 
    { 

     public string urlPath; 


     [Given(@"I have entered 'http://localhost:58529/'")] 
     protected void SetURL() 
     { 
      string URLPath = "http://localhost:58529/"; 
      urlPath = URLPath; 
     } 

     [When(@"I go to that url")] 
     protected void NavigateToURL() 
     { 
      using (var driver = new ChromeDriver()) 
      { 
       driver.Navigate().GoToUrl(urlPath); 
      } 
     } 


     [Then(@"there is a text box on the page with id 'txtNum1'")] 
     protected void TxtBoxExists() 
     { 
      bool txtExists = false; 
      using (var driver = new ChromeDriver()) 
      { 
       IWebElement txtBox1 = driver.FindElement(By.Id("txtNum1")); 

       if (txtBox1 != null) 
       { 
        txtExists = true; 
       } 
      } 
      Assert.AreEqual(true, txtExists); 
     } 
    } 
} 

Насколько я знаю, у меня есть все необходимые ссылки для Visual Studio IDE для SpecFlow/Селен интеграция

References Section

Когда я запустить тест на единицу нагрузки веб-страницы вверх штраф, однако я получаю провальный тест когда Я пытаюсь найти элемент с идентификатором «txtNum1», даже если текстовое поле с таким идентификатором существует на странице

Exception Message

Сведения об исключении выглядеть следующим образом

Exception Details

может указывать никому меня в правильном направлении относительно того, что мне не хватает, чтобы позволить Selenium найти текстовое поле на странице с идентификатором «txtNum1»

+1

Просто первое предположение - shouln't быть 'driver', разделяемого между шаги? –

ответ

1

вы должны использовать один и тот же экземпляр драйвера между шагами, иначе драйвер Навигация к странице отличается от драйвера, с которого вы пытаетесь получить элемент.

у вас есть несколько вариантов для этого. Простейшим является создание поля для вашего экземпляра драйвера и использование поля на всех этапах. Это будет работать до тех пор, пока все ваши шаги находятся в одном файле.

Другой вариант - сохранить объект драйвера в ScenarioContext.Current (или FeatureContext.Current). Это словари, так что вы можете сделать это:

ScenarioContext.Current["webDriver"] = driver; 

Это будет работать нормально, но вы должны бросить каждый раз, когда вы получаете драйвер, как словарь просто принимает объекты, но вы будете иметь возможность поделиться своим драйвера между шагами независимо от того, в каком файле они находятся.

Третья (и наилучшая альтернатива IMHO) - это создать класс WebDriverContext и принять это в своем конструкторе класса шагов.Создайте свой драйвер один раз там (в его конструкторе), а затем каждый шаг может использовать экземпляр WebDriverContext для доступа к совместно используемому драйверу.

Пример настройки этого можно увидеть в answer here

+0

Yeap, который был единственным. Хороший крик об установке общего экземпляра для веб-драйвера – Asif

1

Ваш водитель просто должен немного продолжить медленнее

Добавить некоторую задержку перед каждым driver.FindElement, например, с:

Thread.Sleep(2000); 
IWebElement txtBox1 = driver.FindElement(By.Id("txtNum1")); 

Или еще лучше:

WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0,0,10)); 
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("txtNum1"))); 
IWebElement txtBox1 = driver.FindElement(By.Id("txtNum1")); 
+0

Спасибо за удобный наконечник. Может быть очень полезно, когда у нас есть большая страница для загрузки, и мы хотели бы, чтобы вся страница загружалась сначала, прежде чем искать элемент на ней. Хотя моя особая проблема была вызвана дополнительным экземпляром драйвера chrome. Один экземпляр загружал страницу, а другой оператор «using» использовался для проверки элемента на странице. Поскольку второй экземпляр не загружен на страницу, он всегда возвращал не найденный элемент. – Asif

0

нашел ответ после немного коды экспертизы. Эта проблема связана с несколькими экземплярами ChromeDriver в коде. Таким образом, первый экземпляр загружал страницу, но когда я пытался найти элемент на странице, я использовал новый экземпляр страницы, а не тот, который уже использовался для загрузки страницы. Таким образом, этот второй экземпляр драйвера chrome без загрузки страницы всегда возвращал исключение, поскольку ни один элемент не найден, поскольку на этом экземпляре драйвера хрома не было страницы, загруженной на этот экземпляр драйвера хрома

Смежные вопросы