This code automates the Google sign-in process using Selenium, handling both username and password entry, and includes logic to select an account from multiple options if necessary.
npm run import -- "log in to Google using webdriver"
var matchUsername = 'input[name="Email"], input[autocomplete="username"]';
function enterGoogleUsername(email) {
console.log('Google: Sign in required');
return client
.pause(1000)
.then(() => client.$(matchUsername))
.then(el => el.addValue(email))
.then(() => client.$('#identifierNext'))
.then(el => el.click())
.catch((e) => console.log(e));
}
var matchPassword = 'input[name="Passwd"], input[autocomplete="password"], input[name="password"]';
function enterGooglePassword(pass) {
console.log('Google: Require password');
return client
.pause(2000)
.then(() => client.$(matchPassword))
.then(el => el.addValue(pass))
.then(() => client.$('#passwordNext'))
.then(el => el.click());
}
function enterCredentials(is) {
var credentials = getCredentials('accounts.google.com');
if (is) {
return client.$('#passwordNext')
.then(el => el.isDisplayed())
.then(is => is
? enterGooglePassword(credentials.Passwd)
: enterGoogleUsername(credentials.Email)
.then(() => enterGooglePassword(credentials.Passwd)))
} else {
return client
.findElements('xpath', '//h1[contains(., "Choose an account")]')
.then(is => {
if (is.length > 0) {
return client
.findElements('xpath', '//*[@data-authuser][contains(., "@")]')
.then(is => {
console.log(is);
return is.length > 0
? client.$('//*[@data-authuser][contains(., "@")]').then(el => el.click())
: []
})
.then(() => client.$('#passwordNext'))
.then(el => el.isDisplayed())
.then(is => is
? enterGooglePassword(credentials.Passwd)
: [])
} else {
return client.findElements('xpath', '//h1[contains(., "Sign in")]')
.then(is => is
? enterGoogleUsername(credentials.Email)
.then(() => enterGooglePassword(credentials.Passwd))
: null)
}
})
.catch((e) => console.log(e));
}
}
function loginGoogle() {
return client
.findElements('css selector', 'a[href*="ServiceLogin"]')
.then(is => is.length > 0 ? client.click('a[href*="ServiceLogin"]') : null)
.then(() => client.pause(1000))
.then(() => client.findElements('css selector', 'form[action*="signin"]'))
.then(is => enterCredentials(is.length > 0))
.catch((e) => {
console.log(e);
console.log('Google: Could not log in');
});
}
module.exports = loginGoogle;
// Constants for matching elements on the page
const MATCH_USERNAME = 'input[name="Email"], input[autocomplete="username"]';
const MATCH_PASSWORD = 'input[name="Passwd"], input[autocomplete="password"], input[name="password"]';
class GoogleLogin {
constructor(client) {
this.client = client;
}
/**
* Enters the username in the Google sign-in form
* @param {string} email - The email to enter in the sign-in form
* @returns {Promise} A promise that resolves when the operation is complete
*/
enterGoogleUsername(email) {
console.log('Google: Sign in required');
return this.client
.pause(1000)
.then(() => this.client.$(MATCH_USERNAME))
.then(el => el.addValue(email))
.then(() => this.client.$('#identifierNext'))
.then(el => el.click())
.catch((e) => console.log(e));
}
/**
* Enters the password in the Google sign-in form
* @param {string} pass - The password to enter in the sign-in form
* @returns {Promise} A promise that resolves when the operation is complete
*/
enterGooglePassword(pass) {
console.log('Google: Require password');
return this.client
.pause(2000)
.then(() => this.client.$(MATCH_PASSWORD))
.then(el => el.addValue(pass))
.then(() => this.client.$('#passwordNext'))
.then(el => el.click());
}
/**
* Determines whether to enter a username or password in the Google sign-in form
* @param {boolean} isPassword - Whether to enter a password
* @param {Object} credentials - The credentials to use
* @returns {Promise} A promise that resolves when the operation is complete
*/
enterCredentials(isPassword, credentials) {
return this.client
.$('#passwordNext')
.then(el => el.isDisplayed())
.then(isDisplayed => {
if (isDisplayed) {
return this.enterGooglePassword(credentials.Passwd);
} else if (isPassword) {
// This is redundant, as isPassword is already true
// return this.enterGooglePassword(credentials.Passwd);
return this.enterGooglePassword(credentials.Passwd);
} else {
return this.enterGoogleUsername(credentials.Email).then(() => this.enterGooglePassword(credentials.Passwd));
}
})
.catch((e) => console.log(e));
}
/**
* Logs in to Google
* @returns {Promise} A promise that resolves when the operation is complete
*/
loginGoogle() {
return this.client
.findElements('css selector', 'a[href*="ServiceLogin"]')
.then(is => is.length > 0? this.client.click('a[href*="ServiceLogin"]') : null)
.then(() => this.client.pause(1000))
.then(() => this.client.findElements('css selector', 'form[action*="signin"]'))
.then(is => is.length > 0 && this.enterCredentials(true, getCredentials('accounts.google.com')))
.catch((e) => {
console.log(e);
console.log('Google: Could not log in');
});
}
}
module.exports = (client) => new GoogleLogin(client).loginGoogle();
This code snippet defines functions for automating the Google sign-in process using a Selenium WebDriver client.
Here's a breakdown:
Selectors:
matchUsername
: CSS selector to find the username input field on the Google sign-in page.matchPassword
: CSS selector to find the password input field on the Google sign-in page.enterGoogleUsername
Function:
matchUsername
selector.enterGooglePassword
Function:
matchPassword
selector.enterCredentials
Function:
getCredentials
function (not shown in the snippet).enterGooglePassword
to enter the password.enterGoogleUsername
to enter the email and then enterGooglePassword
to enter the password.