cypressplaywrightplaywright-test

Microsoft Login with Playwright


I have created a Cypress script that perfectly handles the Microsoft login procedure. It looks like this:

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("EMAIL HERE")
                .wait(1000);
            cy.get('.win-button.button_primary.high-contrast-overrides.button.ext-button.primary.ext-primary')
                .contains('Next')
                .should('exist')
                .click({ force: true })
                .wait(5000);
            cy.get('#i0118.form-control.input.ext-input.text-box.ext-text-box', { timeout: 10000 })
                .should('exist')
                .type("PASSWORD HERE")
                .wait(1000);
            cy.get('input#idSIButton9.win-button.button_primary.high-contrast-overrides.button.ext-button.primary.ext-primary')
                .should('exist')
                .click({ force: true })
                .wait(30000);
        });

So it basically opens the login page for the SAP software we use, then it redirects to the Microsoft login which is integrated, inserts the email and password and successfully gets through it.

Now I want to recreate the same procedure with Playwright. I've tried some solutions, following the same steps with Playwright commands, but I get stuck for some reason. The part where I always get stuck is after clicking on the Login with Single Sign on button which should open the Microsoft login page (there where the user is asked to insert their username or email) but it doesnt.

Here is the script I tried to run in Playwright. It didn't get through the Microsoft Login procedure. It basically stuck at the moment when the Playwright should open the Microsoft login page.

test.describe('Replacement Matrix test', () => {
  

  test('should test the replacement matrix', async ({ page, context }) => {
      await page.goto('https://backoffice.iqos.com/backoffice/login.zul', { waitUntil: 'load', timeout: 30000 });
      console.log('Visited the URL successfully');
      await page.waitForTimeout(1000);
      // Click the 'Login with Single Sign On' button
      await page.locator('div.singlesignon_login_cell', { hasText: 'Login with Single Sign On' }).click({ force: true });
      await page.waitForTimeout(20000);

      // Interact with the Microsoft login page
      const microsoftPage = await context.newPage();
      await microsoftPage.goto('https://login.microsoftonline.com');

      // Enter email
      const emailInput = await microsoftPage.waitForSelector('#i0116.form-control.ltr_override.input.ext-input.text-box.ext-text-box', { timeout: 10000 });
      await expect(emailInput).toHaveAttribute('placeholder', 'Email address, phone number or Skype');
      await emailInput.fill('EMAIL HERE');
      await microsoftPage.waitForTimeout(1000);

      // Click 'Next'
      const nextButton = await microsoftPage.locator('.win-button.button_primary.high-contrast-overrides.button.ext-button.primary.ext-primary', { hasText: 'Next' });
      await expect(nextButton).toBeVisible();
      await nextButton.click({ force: true });
      await microsoftPage.waitForTimeout(5000);

      // Enter password
      const passwordInput = await microsoftPage.waitForSelector('#i0118.form-control.input.ext-input.text-box.ext-text-box', { timeout: 10000 });
      await expect(passwordInput).toBeVisible();
      await passwordInput.fill('PASSWORD HERE');
      await microsoftPage.waitForTimeout(1000);

      // Click 'Sign in'
      const signInButton = await microsoftPage.waitForSelector('input#idSIButton9.win-button.button_primary.high-contrast-overrides.button.ext-button.primary.ext-primary');
      await expect(signInButton).toBeVisible();
      await signInButton.click({ force: true });
      await microsoftPage.waitForTimeout(30000);

This script basically opens the first link, and there I instantly notice that it has issues clicking on the Login with Single Sign-on button. After like 15 seconds, it opens the Microsoft login page in the new window, and the test is instantly failed.

Ideally, it should work like this: Step 1: Open https://backoffice.iqos.com/backoffice/login.zul Step2: Click on Login with Single Sign-on button Step 3: The Microsoft login page should open Step 4: Insert email and click on the next button Step 5: Insert password and click on the next button. Step 6: Successfully finished the Microsoft login process.


Solution

  • The basic problem is the div.singlesignon_login_cell contains the <a>Login with Single Sign On</a> but it probably doesn't respond to click().

    Instead you would need to click the <a>Login with Single Sign On</a> directly.

    This is working for me (only part of your test):

    test.only('single sign on', async ({page}) => {
    
      await page.goto('https://backoffice.iqos.com/backoffice/login.zul', 
        {waitUntil: 'load', timeout: 30_000 });
    
      const sso = page.getByRole('link', { name: 'Login with Single Sign On' });
      await sso.click();
    
      // this is on the new page
      await expect(page.getByRole('heading', { name: 'Sign in' })).toBeVisible();
    
      await page.getByPlaceholder('Email, phone, or Skype').click();
      await page.getByPlaceholder('Email, phone, or Skype').fill('my-email');
      await page.getByPlaceholder('Email, phone, or Skype').press('Enter');
    
      await page.pause()
    })
    

    enter image description here

    I used the codegen feature to get the locators, which gives you much better Playwright commands than translating the Cypress stuff, particularly if you're just learning the ropes.

    Basically run Playwright headed

    npx playwright test --headed
    

    and use await page.pause() at the end of your code to pause with the Playwright inspector open.

    enter image description here

    Hit "Record" on the inspector toolbar and the main window gets a toolbar with options for locator, visibility, text and value options.

    Choose which you want to use, then just do the steps on the main form and the Playwright code will be added to the inspector.

    Full documentation is here