替代使用硬编码Xpath查找元素

时间:2017-11-17 03:55:38

标签: c# selenium xpath

我的下面有一个html,其中只包含div标签,包含文本字段和验证消息显示:

<div class="payment-form">
   <div class="payment-form__payment-type">
      <div class="false-label">Payment type</div>
      <div class="form-column">
         <div class="false-label">Name on card</div>
         <div class="form-element-wrapper form-element-wrapper--input-text clearfix form-element-wrapper--error form-element-wrapper--show-label"><label for="name-on-card">Name on card</label> <input name="name-on-card" data-payment-jet2="holderName" id="name-on-card" type="text" maxlength="32" data-vv-id="_0zd5ajemk" aria-required="true" aria-invalid="true"></div>
         <p class="validation-message validation-message--active" style="">Please correct the name on card</p>
      </div>
      <div class="form-column">
         <div class="false-label">Card number</div>
         <div class="form-element-wrapper form-element-wrapper--input-text clearfix form-element-wrapper--error form-element-wrapper--show-label"><label for="card-number">e.g 1111-2222-3333-4444</label> <input type="hidden" data-payment-jet2="number"> <input name="card-number" id="card-number" type="tel" maxlength="23" class="js-payment-card-number" data-vv-id="_wn4jqw3yg" aria-required="true" aria-invalid="true"></div>
         <p class="validation-message validation-message--active" style="">Please correct the card number</p>
      </div>
   </div>
</div>

现在我遇到的问题是验证消息是同一个类:

<p class="validation-message validation-message--active" style="">

在我的selenium中我想确保显示正确的验证,但因为它们具有相同的类,我无法区分它们,除非我使用硬编码的脏xpath,如:

public static By NameOnCardValidation => By.XPath("/html/body/div[1]/div[3]/section/div[6]/div[2]/div/div/div/div/div[3]/p");
public static By CardNumberValidation => By.XPath("/html/body/div[1]/div[3]/section/div[6]/div[2]/div/div/div/div/div[4]/p");

因此,如果对网站进行任何更改,维护很困难,那么我将不得不继续更新这些xpath。

我的问题是,你能看到一种方法,我可以更容易地找到验证消息,而无需像上面那样输入硬编码的xpath吗?只是为了让您知道验证中的消息可能会发生变化,因此在验证消息中查找文本不是一个好主意。

谢谢,

3 个答案:

答案 0 :(得分:0)

正如您所提到的,验证中的消息可能会发生变化,因此我们会创建 xpath ,这些消息独立于Messages。通过动态 xpath ,我们可以控制所有 <p> 标记,其中可能包含以下任何消息:

public static By NameOnCardValidation => By.XPath("//div[@class='payment-form']//following::p[1]");
public static By CardNumberValidation => By.XPath("//div[@class='payment-form']//following::p[2]");

答案 1 :(得分:0)

  

我的问题是,你能找到一种方法,我可以找到   验证消息更容易,无需输入硬编码的xpath   像上面一样?

在这种情况下,我们以简单而通用的方式进行(使用JBehave和java,但这个实现细节并不重要)

在故事层面,有一个简单的Then步骤:

When an user performs some action
Then a message appears on the screen: some message

它的实现如下:

@Then("a message appears on the screen: $message")
public void shoudMeassageAppearOnTheScreen( String message ){
      String xpath = String.format( 
           "//*[contains( @class, 'validation-message' ) and text() = '%s' ]", message 
      );

       WebDriverWait wait = new WebDriverWait( driver, 5 );
       try{ 
          wait.until( ExpecedConditions.visibilityOfElementLocated( By.xpath( xpath ));
      }catch( Exception e ){
         throw new RuntimeException( "Message is not visible: " + message, e );
      }
}

所以我们等待5秒钟的消息,如果它不可见,那么抛出一个带有可理解的错误消息的异常,并且测试失败(由于抛出日志的异常)。

答案 2 :(得分:0)

如果它自己的错误消息没有改变,你应该可以使用以下Xpath:

 //p[contains(text() ='Please correct the card number')]

无论页面在何处,只要实际的错误消息没有改变,它就应该继续工作。我尝试使用[contains]方法完成我对硒的所有工作。它使应用程序更加坚固,并且受html更改的影响较小。如果您对页面有任何控制权,那么在段落中添加id可能是更好的方法。然后你可以使用类似的东西:

 //p[@id='cardnumber_error']