Cypress-Xpath: Correct Xpath syntax for id? It can't find it

Viewed 128

Tried cy.get(#Username) , doesn't work- cypress says it can't find it. could it be related to uppercase letter?

Installed Xpath plugin and used this cy.xpath('//input[@id="Username"]') but it didn't work.

<input type="email" class="form-control" autocomplete="off" data-gd="identity-login-local-form-username" autofocus="" data-val="true" data-val-required="The Username field is required." id="Username" name="Username" value="">

enter image description here

Please before giving -1 , please explain what I need to improve. Thanks!

7 Answers

After downloading xpath plugin, did you add require('cypress-xpath') in your project's cypress/support/index.js file?

According to your example, code below should find the Username

cy.xpath('//input[@id="Username"]')
cy.get('#Username')

The capital letter may be causing the problem. Usually ids have a small letter.

Try using the data-gd attribute instead.

cy.get('[data-gy="identity-login-local-form-username"]')

If that does not work, you may have some shadow DOM before the <input> that blocks the search, in which case you can search inside the shadow like this

it('tests the input', {includeShadowDom:true}, () => {
  cy.get('[data-gy="identity-login-local-form-username"]')
})

I tested with a capital letter cy.get('#Username') and cy.xpath('//input[@id="Username"]') - both worked for me, so likely there is shadow DOM or an <iframe> on your page.

Is it possible that the page has a default namespace? If the page is served as XHTML, it may have a default XML namespace, in which case the input's name is not simply input.

If that is the problem, then you could declare the http://www.w3.org/1999/xhtml namespace and associate it with a prefix, e.g. xhtml (I don't know cypress so not sure how you'd do that), and then query for //xhtml:input[@id="Username"]. An alternative is to query for an element whose local name is input in any namespace at all, e.g. //*[local-name()='input'][@id="Username"]

In case your username field is under a shadow DOM which means other fields will also be under the shadow Dom, it would be advisable to write includeShadowDom: true in your cypress config file to avoid repetition(cypress.json if cypress version < 10; cypress.config.js if cypress version > 10), then directly use the command:

cy.get('#Username').type('username-text')

In case your username field is under an iframe, you can get the cypress iframe plugin

  • To install npm install -D cypress-iframe
  • Go to cypress/support/commands.js file, add the following:
import 'cypress-iframe';
// or
require('cypress-iframe');
  • In your test write:
cy.iframe('#my-frame')
  .find('#Username')
  .should('be.visible')
  .type('username-text')

I can also confirm the way you are selecting the Username input element is correct.

If you suspect shadow DOM is interfering with your test, the best way to debug IMO is to

  • inspect your DOM around the <input>

  • look for a parent element that has #shadow-root below it (in bold)

  • change the test to include this parent

  • add the .shadow() command after the parent to break through the barrier

cy.get('parent-with-shadow-root')
  .shadow()
  .find('#Username')

This debugs and confirms your issue. Everything else, e.g setting global config etc can be done after you know what you have to deal with.

After I tried suggestions and people's confirmation that my xpath was correct, I shifted my focus on the error I got while Cypress was trying to find the element. The error I got was uncaught enter image description hereexception.https://stackoverflow.com/questions/53845493/cypress-uncaught-assertion-error-despite-cy-onuncaughtexception

This error occurs when a module fails to load due to some exception. The error message above should provide additional context. A common reason why the module fails to load is that you've forgotten to include the file with the defined module or that the file couldn't be loaded.

Using ngRoute In AngularJS 1.2.0 and later, ngRoute has been moved to its own module. If you are getting this error after upgrading to 1.2.x or later, be sure that you've installed ngRoute.

Related