This code automates website logins by using Selenium to locate and fill in username, password, and submit fields on various websites. It retrieves login credentials based on the website's hostname and handles potential errors during the process.
npm run import -- "log in to multiple sites"
var url = require('url')
var SIGN_IN = '//a[contains(.,"Sign in")]|//a[contains(.,"Log in")]|//a[contains(.,"Login")]|//a[contains(.,"Log In")]|//a[contains(.,"Sign In")]';
var MATCH_USERNAME = '//input[contains(@name, "Email")]|//input[contains(@name, "email")]|//input[contains(@name, "user")]';
var MATCH_PASSWORD = '//input[contains(@name, "pass")]|//input[contains(@name, "Pass")]|//input[contains(@autocomplete, "pass")]';
var MATCH_SUBMIT = '//*[@type = "submit"]'
// google plus
+ '|//*[@role = "button"][contains(., "Next")]'
// linkedin
+ '|//*[@type = "submit"][contains(., "Sign in")]';
function fillAll(client, obj) {
const promises = [];
for(const k of Object.keys(obj)) {
promises.push((k => resolve => client
.isExisting(k)
.then(is => is && obj[k] !== false
? client.click(k).keys(obj[k])
: (client
? client.click(k)
: []))
.then(() => resolve())
.catch(e => resolve(e))
)(k));
}
return importer.runAllPromises(promises)
}
function multiLogin(client, baseUrl) {
console.log(baseUrl);
const parts = url.parse(baseUrl);
const login = getCredentials(parts.hostname);
const usernameField = Object.keys(login).filter(k => k.match(/user|mail|name/ig))[0];
const passwordField = Object.keys(login).filter(k => k.match(/pass/ig))[0];
return client
.url(baseUrl)
.isExisting(SIGN_IN)
.then(is => is ? client.click(SIGN_IN) : [])
// TODO: check for form elements or URL to see if it needs logging in again like Google an Facebook service do
.then(() => {
const obj = {};
obj[MATCH_USERNAME] = login[usernameField];
obj[MATCH_PASSWORD] = login[passwordField];
obj[MATCH_SUBMIT] = false
return fillAll(obj).then(() => fillAll(obj)).then(() => fillAll(obj))
})
.catch(e => console.log(e))
.getUrl();
}
module.exports = multiLogin
const { JSDOM } = require('jsdom');
const { URL } = require('url');
/**
* Extracts necessary information for multi-login from a given hostname.
* @param {string} hostname The hostname to extract login information from.
* @returns {object} - An object containing username and password fields.
*/
function getCredentials(hostname) {
const domainsToCredentials = {
'google.com': { usernameField: 'identifier', passwordField: 'password' },
'linkedin.com': { usernameField: 'username', passwordField: 'password' },
// Add more domains as needed
};
return domainsToCredentials[hostname] || {};
}
/**
* Fills all form fields with the given values.
* @param {object} client The puppeteer browser client.
* @param {object} obj The object containing form field values.
* @returns {Promise} A promise that resolves with the URL of the current page.
*/
async function fillAll(client, obj) {
const promises = [];
for (const [key, value] of Object.entries(obj)) {
if (!value || await client.isExisting(key)) {
promises.push(client.click(key));
}
if (value!== false) {
promises.push(client.keys(value));
}
}
await Promise.all(promises);
return client.getUrl();
}
/**
* Performs multi-login on the given URL.
* @param {object} client The puppeteer browser client.
* @param {string} baseUrl The base URL to login to.
* @returns {Promise} A promise that resolves with the URL of the current page.
*/
async function multiLogin(client, baseUrl) {
try {
console.log(baseUrl);
const parts = new URL(baseUrl);
const login = getCredentials(parts.hostname);
const usernameField = Object.keys(login).find((k) => k.match(/user|mail|name/ig));
const passwordField = Object.keys(login).find((k) => k.match(/pass/ig));
if (!usernameField ||!passwordField) {
throw new Error(`Unable to determine username and password fields for ${parts.hostname}`);
}
await client.goto(baseUrl);
if (await client.isExisting('a[href*="Sign in"]') || await client.isExisting('a[href*="Login"]')) {
await client.click('a[href*="Sign in"]', 'a[href*="Login"]');
}
const obj = {
[`${login[usernameField]}`]: login[usernameField],
[`${login[passwordField]}`]: login[passwordField],
};
return await fillAll(client, obj);
} catch (error) {
console.error(error);
return '';
}
}
module.exports = multiLogin;
This code snippet appears to be designed for automating logins to various websites. Here's a breakdown:
Variables:
url
: A module for parsing URLs.SIGN_IN
, MATCH_USERNAME
, MATCH_PASSWORD
, MATCH_SUBMIT
: Regular expressions used to locate specific elements on web pages (sign-in buttons, username/password fields, and submit buttons).Functions:
fillAll(client, obj)
:
client
) and an object (obj
) containing field names and their corresponding values.multiLogin(client, baseUrl)
:
client
) and a base URL (baseUrl
).getCredentials
(not shown) based on the hostname.fillAll
three times to fill the form fields.Purpose:
This code snippet provides a framework for automating the login process to multiple websites. It uses Selenium to interact with web pages, locate form elements, and fill them with credentials retrieved from a separate function.
Let me know if you have any other questions.