javascriptasync-awaitprotractorclickable

Protractor element not clickable at point


I'm trying to login to a google account using protractor

google-account-spec.js

const loginPage = require('../pages/login-page');
const EC = ExpectedConditions;

describe('google accounts', function () {
it('should log in', async function () {
    try {
        browser.waitForAngularEnabled(false);
        browser.ignoreSynchronization = true;
        browser.get('https://accounts.google.com/signin/v2/identifier?flowName=GlifWebSignIn&flowEntry=ServiceLogin');
        //writing my email into an email input
        await loginPage.sendKeysEmailInput('email');
        //clicking on the next button for the email input
        loginPage.getEmailNextButton().click();
        await browser.wait(EC.presenceOf(loginPage.getPasswordInput()), 300000);
        let id = await loginPage.getPasswordInput().getAttribute('id');
        await browser.wait(EC.elementToBeClickable(element(by.name(id))), 300000);
        //writing my password into password input
        await element(by.name(id)).sendKeys('password');
        //waiting for the next button for the password input to become clickabe            
        await browser.wait(EC.elementToBeClickable(element(by.id('passwordNext'))), 5000);
        await browser.wait(EC.presenceOf(element(by.id('passwordNext'))), 5000);
        //trying to click on next button for the password input and getting an error
        await element(by.id('passwordNext')).click();
    } catch (expection) {
        console.error(expection);
    }
});
});

conf.js

exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
onPrepare : function() {
    // browser.manage().window().setSize(1600, 1000);
    browser.manage().window().maximize();
},
capabilities: {
    'browserName': 'chrome'
},
specs: ['specs/google-accounts-spec.js'],
jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 3000000,
}
};

login-page.js I'm using a PageObject pattern(login-page is a page object)

var loginPage = function () {
var emailInput = element(by.id('identifierId'));
var passwordInput = element(by.id('password'));
var emailNextButton = element(by.id('identifierNext')).element(by.tagName('span'));


this.sendKeysEmailInput = async function(keys) {
    await emailInput.clear().sendKeys(keys);
};

this.getPasswordInput = function () {
    return passwordInput;
};

this.sendKeysPasswordInput = async function(keys) {
    await passwordInput.clear().sendKeys(keys);
};

this.getEmailNextButton = function(){
    return emailNextButton;
}
};

module.exports = new loginPage();

When I try to click on the next button for the password input I'm getting an error

{ WebDriverError: unknown error: Element ... is not clickable at point (1100, 527). Other element would receive the click:

It says that the element isn't clickable, but previously in the code I had waited for it to become clickable. So I just don't get it, how can this element not be clickable.

I also tried maximizing the window in onPrepare in conf.js but still got the same error.

The odd thing is that I don't get this error all the time, it occurs like in 1 of 3 tries. I suppose that's because of my high internet speed.

I know that there is a simple way of solving this by just writing browser.sleep() but I think that there is a better and faster solution, because with browser.wait() you can wait much more than you actually should've, as a result, my program would become much slower.


Solution


  • this can occur due element you wish to click is wrapped. For example you wish to click 'input' but his wrapper 'div' has to be clicked and can throw error in that case. To bypass this issue, you can click the wrapper or execute JS click.

    export async function jsClickButton(button: ElementFinder) {
    
        try {
            return await browser.executeScript('arguments[0].click()', button).then(async() => {
                console.log('Element has been clicked.');
            });
        } catch (error) {
            console.log('Element could not be clicked', error);
        }
    }