0

I'm trying automate an Angular application. The only drawback I have at the moment is that I don't want to use Protractor, I want to automate using Selenium/Eclipse. I have tried it but the problem is that locator keeps changing whenever I rerun the test. I have browsed through the net and found no concrete solution to this. Snippet of one field in the websites:

<input _ngcontent-wle-c93="" formcontrolname="FirstName" mattooltip="Enter First Name" maxlength="50" matinput="" placeholder="First Name" class="mat-input-element mat-form-field-autofill-control ng-tns-c47-3 ng-pristine ng-invalid ng-touched" cdk-describedby-host="" id="mat-input-0" aria-invalid="true" aria-required="false" aria-describedby="mat-error-0">

id="mat-input-0" keeps changing

1
  • Then use one of the attributes that doesn't change, or add your own more stable locators (e.g. data-test-id="some-useful-input"). Even if you are using Protractor that's better than coupling your E2E tests to Angular. Commented Sep 21, 2020 at 16:41

2 Answers 2

2

For your element, you have a couple of options to access it

<input _ngcontent-wle-c93="" formcontrolname="FirstName" mattooltip="Enter First Name" maxlength="50" matinput="" placeholder="First Name" class="mat-input-element mat-form-field-autofill-control ng-tns-c47-3 ng-pristine ng-invalid ng-touched" cdk-describedby-host="" id="mat-input-0" aria-invalid="true" aria-required="false" aria-describedby="mat-error-0">

Let's take it one by one

CSS_SELECTOR

drive.findElement(By.cssSelector("input[formcontrolname='FirstName'][placeholder='First Name']"));

XPATH

drive.findElement(By.xpath("//input[contains(@placeholder,'First Name')]"));

or

drive.findElement(By.xpath("//input[contains(@formcontrolname,'FirstName')]"));

or both

drive.findElement(By.xpath("//input[contains(@formcontrolname,'FirstName') and (@placeholder, 'FirstName')]"));

same for CSS_SELECTOR - I've shown to you the code with both, but you can access it even by specifying one attribute for your input element

Sign up to request clarification or add additional context in comments.

2 Comments

Loads of Thanks. Your answer was the perfect solution. This is what I was looking for. Although CSS worked perfectly and I assume xpath would have worked as well but when I rechecked the code, it had "matinput placeholder" not just "placeholder". I tried with the matinputplaceholder but did not work. If you could just tell me why it did not work, that would be great. Again, Thanks a bunch.
matinput is an empty attribute, you cannot use it as [matinputplaceholder] cause placeholder is an attribute that has value, if you set matinput value in code, your browser will generate it differently and then you can use it //input[contains(@matinput, 'value') and (@placeholder,'value')]
0

To identify the element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:

  • Using and XPATH:

    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[contains(@class, 'mat-input-element') and @formcontrolname='FirstName'][@placeholder='First Name']"))).click();
    
  • Using and CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.mat-input-element[formcontrolname='FirstName'][placeholder='First Name']"))).click()
    
  • Note : For python clients you have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.