简体   繁体   English

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

[英]Alternative to finding elements using hard coded Xpath

I have a html below that contains simply div tags that within contain text fields and a display for validation messages: 我下面有一个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>

Now the problem I am having is with the validation messages which are the same class: 现在我遇到的问题是同一类的验证消息:

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

In my selenium I want to ensure the correct validation is displayed but because they have the same class, I cannot differentiate between then unless I use a hard coded dirty xpath like: 在我的硒中,我想确保显示正确的验证,但是由于它们具有相同的类,因此除非使用了硬编码的脏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");

Thus makes maintenance difficult as if there are any changes to the website, then I will have to keep updating these xpaths. 这样就使得维护工作变得困难,好像网站上有任何更改一样,那么我将不得不不断更新这些xpath。

My question is that can you see a way where I can locate the validation messages a lot easier without entering a hard coded xpath like above? 我的问题是,您能找到一种无需输入像上面这样的硬编码xpath就能更轻松地找到验证消息的方法吗? Just to let you know the messages in the validation may change so it would not be a good idea to look for the text within the validation message. 只是为了让您知道验证中的消息可能会更改,因此在验证消息中查找文本并不是一个好主意。

Thanks, 谢谢,

As you mentioned that the messages in the validation may change so we will create xpath those are independent of the Messages . 正如您所提到的,验证中的消息可能会更改,因此我们将创建独立于Messages xpath Through our dynamic xpath we will be able to control all the <p> tags which may contain any message as follows : 通过我们的动态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]");

My question is that can you see a way where I can locate the validation messages a lot easier without entering a hard coded xpath like above? 我的问题是,您能找到一种无需输入像上面这样的硬编码xpath就能更轻松地找到验证消息的方法吗?

In such cases we do it in a simple and general way (using JBehave and java, but that's implementation details that do not matter) 在这种情况下,我们以简单通用的方式进行操作(使用JBehave和Java,但这无关紧要的实现细节)


At the story level there is simple Then step: 在故事级别,有一个简单的“ Then步骤:

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

and it's implementation looks like this: 它的实现如下所示:

@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 );
      }
}

so we are waiting 5 seconds for the message, if it is not visible, then an exception is thrown with a understandable error message, and a test fails (due to the exception thrown to the log). 因此,我们正在等待5秒钟的消息,如果该消息不可见,则会引发带有可理解的错误消息的异常,并且测试失败(由于引发了异常的日志)。

Providing that the error message it self doesn't change you should be able to use the following Xpath: 如果错误消息本身不会改变,则您应该可以使用以下Xpath:

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

No matter where it is on the page it should continue to work as long as the actual error message doesn't change. 不管它在页面上的什么位置,只要实际的错误消息没有变化,它都应继续工作。 I try to use the [contains] approach for all of the work I do with selenium. 我尝试使用[contains]方法进行硒的所有工作。 It makes the application more sturdy and less affected by html changes. 它使应用程序更加健壮,并且不受html更改的影响较小。 If you have any control over the page then adding an id to the paragraph would probably be a better way to do it. 如果您对页面有任何控制权,则在段落中添加ID可能是一种更好的方法。 Then you can use something like: 然后,您可以使用类似:

 //p[@id='cardnumber_error']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM