//a[@type='text'][contains(@class,'form-control')][contains(@name,'projectsurvey')]

Do we have a way when the element name changes from input to some other For Example : class then definitely script fails. So do we have any other different ways to identify the element on the page if any changes are done on the page?

//input[@type='text'][contains(@class,'form-control')][contains(@name,'projectsurvey')]

You can see in the above xpath it got changed from //a to //input then script is unable to identify this element on the page.

I can see the only external type is changing rest of the properties remains same. //a from // input replace this by //*

Use this below code:

 //*[@type='text'][contains(@class,'form-control')][contains(@name,'projectsurvey')]
  • What if the form has 2+ input or anchor elements ? – Michael Durrant Jul 6 at 12:00
  • @MichaelDurrant I think in that case you can use index to specify which one you're going to interact with. Personally my impression is that OP sets kinda false target since if your test is awaiting <a> but gets <input> in the most of the cases it would be a defect. Hence here we shouldn't expect an elegant answer since the question is not elegant. – Alexey R. Jul 6 at 17:40

The approach to use is to try and not include such elements in your selector.

Generall this means don't hard code the entire selector (starting from body or some other elements) cos the page may change at some point. As you have discovered.

So in this case I would look to use the selector

 //*[@type='text'][contains(@class,'form-control')][contains(@name,'projectsurvey')]

This is not guaranteed to work. For example you might have both a label and an input/anchor field that would both be selected using this. You could get around this either using an index, e.g.

      //*[@type='text'][contains(@class,'form-control')][contains(@name,'projectsurvey')][0] 

or by adding an actual ID to the element if you have access or ability to get the HTML itself changed, e.g.

      //*[@id='project_survey_name']

As you can see the above would be the desirable way.

For all these approaches I would also use css which is easier to read and maintain IMHO, e.g.

      *#project_survey_name

Short answer:

In order to avoid creating complicated locators, which are more error-prone and difficult to maintain, you can catch the failure of locating the link and try the below code:

getDynamicElement() {
    try{
        return driver.findElement(locatorForTheLink);
    } catch (ElementNotFound e) {
        return driver.findElement(locatorForTheInput);
   }

Long answer:

Remember you have control over the application execution. If your previous actions triggered a change in the element type, maybe you should called it differently, Creating a new element with a new locator. With the same element either be a link or an input field will be confusing and difficult to maintain in future.

Example:

...sequence of actions which make the element stay as a link
page.clickOnMyLink();
...sequence of actions which make the element change to a input
page.insertTextInTheInput('inputed text');

clickOnMyLink() {
    this.link.click();
}

insertTextInTheInput(text) {
    this.input.insert(text);
}

The attribute link would match a link (HTML tag a) and the attribute input would match a input (HTML tag input).

That way, whenever someone try to click on the input or insert text in the link, it would raise, correctly, an error. Additionally, the test clearly states that you are trying to use either a link or a input.

Keep things dry and direct is better than complex and smart.

  • can you please explain with example so it will be easy to understand. – vishnu sharma Jul 6 at 7:33
  • i easily get to know the reasons whenever it fails so do we have any way to locate a element which does not fail using xpath. – vishnu sharma Jul 6 at 7:35
  • @vishnusharma I tried to exemplify my "long answer". Tell me what you think. – João Farias Jul 6 at 13:07

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.