src/controllers/web/login.controller.js
import * as WebPageObjects from "../../page_objects/web/webPageObjects.js";
import BaseController from "./base.controller.js";
import fs from "fs";
import { getLoginCookies } from "../../../src/utils/getLoginCookies.js";
/**
* Controller to perform login related actions
* @extends BaseController
*/
class LoginController extends BaseController {
/**
* @param {Object} args Args from client
*/
constructor(args) {
super(args);
this.loginPage = new WebPageObjects.LoginPage(args);
this.homePage = new WebPageObjects.HomePage(args);
this.headerPanel = new WebPageObjects.HeaderPanel(args);
this.onboardingPage = new WebPageObjects.OnboardingPage(args);
}
/**
* Bypasses normal login page then sets cookies,
* then navigates to /auth to login.
* @param {String} email - email of user
* @param {String} password - password of user
* @example loginWithCookies('test@lifesize.com', 'password123')
*/
async loginWithCookies(email, password) {
try {
await this.preLogin();
const cookies = await getLoginCookies(email, password);
await this.browser.execute(cookies => {
document.cookie = cookies.fullA; // eslint-disable-line
document.cookie = cookies.fullClient; // eslint-disable-line
}, cookies);
await this.browser.url(BASE_URL);
await this.waitUntilIsLoggedIn();
await this.setSkipAlertOnClose();
} catch (error) {
console.log("ISSUE LOGGING IN VIA API!!!"); // eslint-disable-line
const browserLogs = await this.browser.log("browser");
const testName = this.testName.replace(/[^A-Z0-9]+/gi, "_");
const fileName = `./browser_logs/${testName}.${Date.now()}.browserLogs.txt`;
fs.writeFile(fileName, JSON.stringify(browserLogs, null, 2), err => {
if (err) {
console.log("Error saving browser logs"); // eslint-disable-line
throw err;
}
});
console.log("Wrote browser logs to:", fileName); // eslint-disable-line
throw error;
}
await this.browser.pause(3000);
}
/**
* Logs in via the normal login page
* @param {String} email - email of user
* @param {String} password - password of user
* @example login('test@lifesize.com', 'password123')
*/
async login(email, password) {
try {
await this.preLogin();
await this.loginPage.visit();
await this.loginPage.login(email, password);
await this.browser.pause(10000);
await this.waitUntilIsLoggedIn();
await this.setSkipAlertOnClose();
} catch (error) {
console.log(this.testName + " - ISSUE LOGGING IN MANUALLY!!!"); // eslint-disable-line
const browserLogs = await this.browser.log("browser");
const testName = this.testName.replace(/[^A-Z0-9]+/gi, "_");
const fileName = `./browser_logs/${testName}.${Date.now()}.browserLogs.txt`;
fs.writeFile(fileName, JSON.stringify(browserLogs, null, 2), err => {
if (err) {
console.log(this.testName + " - Error saving browser logs"); // eslint-disable-line
throw err;
}
});
console.log(this.testName + " - Wrote browser logs to:", fileName); // eslint-disable-line
throw error;
}
await this.browser.pause(3000);
}
/**
* Pre login steps to set onboarded local storage and disable walkme
*/
async preLogin() {
await this.browser.url(`${BASE_URL}/missingExtension`);
await this.setOnboarded();
await this.disableWalkMe();
await this.setForcedIp();
}
/**
* Logs out of the app
* */
async logout() {
await this.headerPanel.logout();
await this.waitUntilIsLoggedOut();
}
/**
* Disable walk me from showing
*/
async disableWalkMe() {
await this.browser.localStorage("POST", {
key: "disableWalkMe",
value: "true"
});
await this.browser.pause(1000);
}
/* eslint-disable complexity */
/**
* Waits up to 30 seconds to be considered logged in
* @example client.loginController.waitUntilIsLoggedIn()
*/
async waitUntilIsLoggedIn() {
// Check if we errored out on the login form
const error = await this.checkForLoginErrors();
if (error) {
throw new Error(this.testName + " - Issue on login form:" + error);
}
// Check if we are still on the purple loading screen
await this.browser.waitUntil(
async () => (await this.isLoggingIn()) === false,
30000,
this.testName + " - Still on the loading animation prior to login."
);
// Check to see if kicked back to login form
if (await this.loginPage.emailField().isVisible()) {
throw new Error(
this.testName + " - Got kicked back to login form after loading screen."
);
}
// Finally, confirm we are logged in.
await this.browser.waitUntil(
async () => {
await this.onboardingPage.bypass();
return await this.isLoggedIn();
},
30000,
this.testName + " - Should be on homepage, but not considered logged in."
);
}
/* eslint-enable complexity */
/**
* Wait until user is considered logged out
*/
async waitUntilIsLoggedOut() {
await this.browser.waitUntil(
async () =>
(await this.isLoggedOut()) ? true : await this.browser.pause(1000),
30000,
this.testName + " - Not completely logged out."
);
}
/**
* Determines if user is currently logging in
* @returns {Boolean} True if considered logging in
*/
async isLoggingIn() {
return await this.loginPage.loadingCircle().isVisible();
}
/**
* Determines if user is logged in
* @returns {Boolean} True if welcome message is visible
* @todo check more things to be considered 'logged in'?
*/
async isLoggedIn() {
return await this.homePage.isWelcomeMessageVisible();
}
/**
* Determinse if user is considered logged out
* @returns {Boolean} True if considered logged out
*/
async isLoggedOut() {
const visible = await this.headerPanel.availabilityDropdown().isVisible();
return !visible;
}
/**
* Checks for errors on the login page
* @returns {String} Text of error message or null
*/
async checkForLoginErrors() {
if (await this.loginPage.errorMessage().isVisible()) {
return await this.loginPage.errorMessage().getText();
} else {
return null;
}
}
/**
* When closing browser or navigating away, we are presented with an alert.
* This run js on the page that tells the app to skip this alert.
* Hard coded to 300,000ms (5 minutes)
*/
async setSkipAlertOnClose() {
// checking for lsConfig so we can skip the alert upon closing browser
await this.browser.waitUntil(
async () => await this.browser.execute("!!window.lsConfig"),
10000,
this.testName + " - lsConfig is not found"
);
// window.desktop = true
await this.browser.execute(
"window.lsConfig.skipTimeOnBeforeUnload(900000)"
);
}
/**
* Set onboarded local storage to true
*/
async setOnboarded() {
await this.browser.localStorage("POST", {
key: "onboarded",
value: "true"
});
}
/**
* Set Forced CSS IP
*/
async setForcedIp() {
if (process.env.FORCED_IP) {
await this.browser.localStorage("POST", {
key: "ipAddressOverride",
value: process.env.FORCED_IP
});
}
}
}
export default LoginController;