简体   繁体   中英

E2E Test with Protractor and Angular: Make protractor wait while browser is loading

I'm testing a webpage that is accessing a third website for handling the login (oAuth). In order to test my webpage, I first need to make my e2e test log in at the third website. I'm able to locate the input element for the user email address on the third website and enter it. Then I'm also able to click on the "Continue" button, where the third website now opens a new fragment to enter the passowrd.

The problem comes then: The password field is not interactable and I get following error:

 - Failed: element not interactable
    (Session info: chrome=87.0.4280.141)
    (Driver info: chromedriver=87.0.4280.20 (c99e81631faa0b2a448e658c0dbd8311fb04ddbd-refs/branch-heads/4280@{#355}),platform=Windows NT 10.0.17763 x86_64)

I think the reason is that the page didn't render the new fragment yet, so the passwort input field is not visible yet. So I used browser.sleep(1000) , but this stops the browser too, right? So then after that 1000 ms passed, the fragment is still not loaded. I know there's also something with

browser.wait(EC.urlContains("The URL of the password input page"))), 1000);

The problem here is that the URL of the "Enter Email"-Part and the "Enter-Password"-Part are the same, so this command will check the URL and immediately continue.

I also tried this:

element(by.id("<id of the continueButton on the login fragment>).click().then(() => {
 ->perform my other actions for the passowrt part here
})

But it doesn't work, the Promise that is returned from click() is immediately resolved after the click happened I think, so the page still didn't get to the passowrd part.

Here's my code so far:

describe('workspace-project App', () => {

  it('Login at third website works.', async () => {
    await browser.get('https://my-webiste.com');
    
    const startButton = element(by.tagName('button'));
    startButton.click();
    // after clicking the start button on my page we get redirected to the login page of my 
    // oauth provider (third website) 
    browser.sleep(100)
    browser.getCurrentUrl().then(url => {
        expect(url.split("?")[0]).toEqual('https://my-oauth-login-page.com/login/gb/en_GB')
      })

    const inputEmail = element(by.id('username'));
    const LogInButtonEmail = element(by.tagName('button'));
      
    await inputEmail.sendKeys("<user-email-address for login>");
    browser.sleep(100)
    LogInButtonEmail.click();
    browser.sleep(1000)
    //until here everything works fine, but now we open the new fragment for entering the password and the test failsbefore the fragment gets shown:

    const inputPassword = element(by.id('current-password'));
    const LogInButtonPassword = element(by.tagName('button'));
    await inputPassword.sendKeys("<user-password for login>");
    browser.sleep(100)
    LogInButtonPassword.click();
    browser.sleep(100)
      
    browser.getCurrentUrl().then(url => {
        expect(url).toEqual('https://my-website-URL-after-successfull-redirect-from-oauth.com')
    })

  });

  afterEach(async () => {
    // Assert that there are no errors emitted from the browser
    const logs = await browser.manage().logs().get(logging.Type.BROWSER);
    expect(logs).not.toContain(jasmine.objectContaining({
      level: logging.Level.SEVERE,
    } as logging.Entry));
  });
});

When I make the browser sleep for longer and enter the password by hand manually in the browser that was opened by protector, the login succeeds and all following test for my website pass. Gosh I wished they had put email and password on the same view/fragment then it would be no problem, arg...

Any tips are welcome; )

In protractor everything is a promise you should wait for promise to be resolved

await browser.wait(EC.urlContains("The URL of the password input page"))), 1000);

Await can be used only inside a async function as you have declared it block as async you can use await

await browser.sleep(3000) will not stop browser, it just stop protractor from sending commands to browser for 3 seconds. It's same like adding script sleep

browser.wait(EC.elementToBeVisible($('Password field')), 10000);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM