Search code examples
authenticationautomated-testscypress

Cypress can't find the password field in the Microsoft Login


I've done some testing with Cypress that requires the Microsoft login. I got stuck at the part that I initially thought would be easy, which was typing in the password. In order to better explain the issue here, lemme list the steps included in this testing:
Step 1: Navigate to the link (this is the platform I'm doing testing on)

https://backoffice.iqos.com/backoffice/login.zul

Step 2: Click on the Login with Single Sign On button that will open the Microsoft Login page.

Step 3: Type in the Username/Email

Step 4: Click on the Next button.

Step 5: Type in the password field the password (here I got stucked)

Step 6: Click on the Sign-in button.

Here is the code source that is containing the Password field element including the parent elements:

<div data-testid="inputComponentWrapper" class="___102hf4m f1tyq0we f11qmguv f1wv5yrl"><div>

<div class="___917j710 ftgm304 fly5x3f fwrgwhw f15tpi3i f10pi13n frecw6t f1mmgjok f1tto2h8 f1c2pb84 fyft3pb f1rof34y f1172n73 f4hylce f18s3fau f1ymw6u3 f1xqrj1d f160kle0 f6rydpu f1i9lmva fspveqh f2x7bcd f1imcvf3 f1bxicz3 f1kf6f3a fajq0z4 fyw0hav f1a7xkls fnpm3l fsc3mvo f1s66rt0 f73ugz1 f1iw8vv5 f5iv370 f1ytw2m8 feh5m5c f7upnml fexuuuk fklagwq fsjklvg f1uvsclk f123zcai">

<input id="i0118" data-testid="i0118" name="passwd" placeholder="Password" type="password" maxlength="120" aria-label="Enter the password for addusernamehere" aria-describedby="loginHeader " class="" autocomplete="current-password" value="" style="border-color: rgb(102, 102, 102);"></div></div></div>

This is the script I've used for testing:

beforeEach(() => {
      cy.visit('https://backoffice.iqos.com/backoffice/login.zul', { failOnStatusCode: false, timeout: 30000 }).then(() => {
          cy.log('Visited the URL successfully');
      }).wait(1000);
  });

  it('should test the replacement matrix', () => {
      cy.get('div.singlesignon_login_cell')
          .contains('Login with Single Sign On')
          .should('exist')
          .click({ force: true })
          .wait(20000);

      cy.origin('https://login.microsoftonline.com', () => {
          cy.get('#i0116.form-control.ltr_override.input.ext-input.text-box.ext-text-box', { timeout: 10000 })
              .should('have.attr', 'placeholder', 'Email address, phone number or Skype')
              .type("ADD USERNAME HERE")
              .wait(1000);
          cy.get('.win-button.button_primary.button.ext-button.primary.ext-primary')
              .contains('Next')
              .should('exist')
              .click({ force: true })
              .wait(5000);
              cy.get('div[data-testid="inputComponentWrapper"]') // Target the parent div
  .find('input#i0118[name="passwd"]') // Find the input element inside
  .should('be.visible') // Ensure the element is visible
  .and('have.attr', 'type', 'password') // Check it's a password field
  .and('have.attr', 'aria-label') // Verify the aria-label attribute exists
  .type('yourpasswordhere', { log: true }) // Type the password
          cy.get('.win-button.button_primary.button.ext-button.primary.ext-primary')
              .should('exist')
              .click({ force: true })
              .wait(30000);
      });

This script fail at this point:

cy.get('div[data-testid="inputComponentWrapper"]')

Another thing I've tried, but it didn't work, was searching for the field by its placeholder only:

cy.get('input[placeholder="Password"]') // Target the input by its placeholder .should('be.visible') // Ensure the element is visible
.type('yourpasswordhere', { log: true }) // Type the password


Solution

  • took me a while but figured it out, it's because when you reach the password field the domain changes from login.microsoftonline.com to login.live.com so you have to put a second cy.origin() there.

          cy.visit('https://backoffice.iqos.com/backoffice/login.zul', { failOnStatusCode: false, timeout: 30000 }).then(() => {
              cy.log('Visited the URL successfully');
          }).wait(1000);
      });
    
      it('should test the replacement matrix', () => {
          cy.get('div.singlesignon_login_cell')
            .contains('Login with Single Sign On')
            .should('exist')
            .click({ force: true })
    
          cy.origin('https://login.microsoftonline.com', () => {
            cy.get('#i0116.form-control.ltr_override.input.ext-input.text-box.ext-text-box', { timeout: 10000 })
              .should('have.attr', 'placeholder', 'Email address, phone number or Skype')
              .type("ADD USERNAME HERE")
            cy.get('.win-button.button_primary.button.ext-button.primary.ext-primary')
              .contains('Next')
              .should('exist')
              .click({ force: true })
          })
          
          cy.origin('https://login.live.com', () => {
            cy.get('div[data-testid="inputComponentWrapper"]') // Target the parent div
              .find('input#i0118[name="passwd"]') // Find the input element inside
              .should('be.visible') // Ensure the element is visible
              .type('yourpasswordhere', { log: true }) // Type the password
            cy.get('button[type="submit"]')
              .should('exist')
              .click({ force: true })
          });
        }) 
    

    As a sidenote, your .wait() are absolutely crazy, you shouldn't need those in this case, especially not some that are 20-30s long so i removed them (it worked perfectly fine without them for me). I suppose you already added experimentalModifyObstructiveThirdPartyCode: true, to your config file, if not you should probably do this. also the submit button for me had a different class so i just used type=submit

    If it now finds everything but fails due to an uncaught exception then add to your testfile

    Cypress.on('uncaught:exception', (err, runnable) => {
        // returning false here prevents Cypress from
        // failing the test
        return false
    })
    

    Now it should work! Edit: made the rest of the code work aswell