tia
Version:
Time is All (logs driven test engine with ExtJs support)
306 lines (254 loc) • 10.6 kB
text/typescript
import { Options as ChromeOptions } from 'selenium-webdriver/chrome';
import { Options as FirefoxOptions } from 'selenium-webdriver/firefox';
import * as util from 'util';
import { EnableLog } from '../common-types';
// TODO: does not driver creates profile dir itself ?
// function createBrowserProfile() {
// fileUtils.mkdir(gT.config.browserProfilePath);
// }
const cleanedProfilePaths: string[] = [];
export async function init(cleanProfile?: boolean, enableLog?: EnableLog) {
// if (typeof enableLog === 'undefined' && !gT.config.browserProfileDir) {
// enableLog = false;
// }
gIn.tracer.msg3(`browserProfilePath: ${gT.config.browserProfilePath}`);
gIn.tracer.msg3(`shareBrowser: ${gT.cLParams.shareBrowser}`);
gIn.tracer.msg3(`sharedBrowserInitiated: ${gIn.sharedBrowserInitiated}`);
// If directory has private profile, --share-browser is ignored.
if (!gT.config.browserProfileDir && gT.cLParams.shareBrowser) {
if (gIn.sharedBrowserInitiated) {
gIn.tracer.msg3('Initialization is not needed');
return Promise.resolve('Initialization is not needed');
}
gIn.sharedBrowserInitiated = true;
}
let profileInfo;
if (gT.config.browserProfileDir) {
profileInfo = `(with dir-config defined ${cleanProfile ? 'empty' : 'saved'} profile)`;
} else {
profileInfo = '(with default profile)';
}
return gIn.wrap({
msg: `Initialization ${profileInfo} ... `,
enableLog,
act: async () => {
if (cleanProfile) {
gT.s.browser.cleanProfile(false);
} else if (
gT.cLParams.clearProfiles &&
!cleanedProfilePaths.includes(gT.config.browserProfilePath)
) {
gT.s.browser.cleanProfile(true);
cleanedProfilePaths.push(gT.config.browserProfilePath);
}
// createBrowserProfile();
let options: ChromeOptions | FirefoxOptions;
switch (gT.cLParams.browser) {
case 'chrome':
options = new gT.sOrig.chrome.Options();
options.addArguments('--dns-prefetch-disable');
options.addArguments('--no-sandbox'); // Without this there is a fail with xvfb on Ubuntu 16.
options.addArguments('--disable-infobars');
if (gT.cLParams.headless) {
options.addArguments('--headless');
options.addArguments('--window-size=2560,1024');
if (gT.u.misc.isWindows()) {
options.addArguments('--disable-gpu'); // Temporary fix for Windows.
}
}
// options.addArguments('--start-maximized');
// if (gT.config.browserProfileDir) {
options.addArguments(`--user-data-dir=${gT.config.browserProfilePath}`);
// }
// options.excludeSwitches();
options.setUserPreferences({
credentials_enable_service: false,
'profile.password_manager_enabled': false,
});
break;
case 'firefox':
{
options = new gT.sOrig.firefox.Options();
// const binary = new gT.sOrig.firefox.Binary();
// if (gT.config.browserProfileDir) {
// Profile name should be alphanumeric only.
// Checked on linux. It does set -profile option.
// binary.addArguments('-profile "' + gT.config.browserProfilePath + '"');
options.setProfile(gT.config.browserProfilePath); // Checked on linux. Does NOT set -profile option.
// http://selenium.googlecode.com/git/docs/api/javascript/module_selenium-webdriver_firefox.html
// "The FirefoxDriver will never modify a pre-existing profile; instead it will create
// a copy for it to modify."
// http://stackoverflow.com/questions/6787095/how-to-stop-selenium-from-creating-temporary-firefox-profiles-using-web-driver
// webdriver.firefox.profile (name of the profile).
// Also there is info that gT.sOrig.driver.quit() deletes tmp profile, butgT.sOrig.driver.close()
// - does not.
// profile.setPreference ?
// browser.sessionstore.resume_from_crash
// writeToDisk ?
// }
if (gT.cLParams.headless) {
options.headless();
}
// options.setBinary(binary);
// gT.sOrig.wdModule.Capabilities.firefox();
// capabilities = new gT.sOrig.wdModule.Capabilities();
}
break;
}
const prefs = new gT.sOrig.wdModule.logging.Preferences();
// TODO: this parameter correctly works only for chrome.
// phantomjs gets all messages, independent on choosen level.
// Mozilla gets no messages.
prefs.setLevel(gT.sOrig.browserLogType, gT.cLParams.browserLogLevel);
prefs.setLevel(gT.sOrig.driverLogType, gT.cLParams.driverLogLevel);
const capabilities = new gT.sOrig.wdModule.Capabilities();
// Waiting to my PR approve for DefenitelyTyped.
// @ts-ignore
capabilities.setBrowserName(gT.cLParams.browser);
capabilities.setLoggingPrefs(prefs);
gIn.tracer.msg3(util.inspect(capabilities, { depth: 4 }));
if (gT.cLParams.useRemoteDriver) {
const sid = gIn.remoteDriverUtils.getSid();
const remoteDriverConnectionStr = `${gT.globalConfig.remoteDriverUrl}:${gT.globalConfig.remoteDriverPort}`;
if (sid) {
gIn.tracer.msg3('There is current SID');
gT.firstRunWithRemoteDriver = false;
const client = new gT.sOrig.Client(remoteDriverConnectionStr);
const executor = new gT.sOrig.Executor(client);
// @ts-ignore
executor.w3c = true;
// gT.sOrig.driver = new gT.sOrig.wdModule.WebDriver(sid, executor);
const session = new gT.sOrig.wdModule.Session(sid, {});
gT.sOrig.driver = new gT.sOrig.wdModule.WebDriver(session, executor);
} else {
gIn.tracer.msg3('There is not current SID');
gT.firstRunWithRemoteDriver = true;
gT.sOrig.driver = new gT.sOrig.wdModule.Builder()
.forBrowser(gT.cLParams.browser)
.setChromeOptions(options! as ChromeOptions)
.setFirefoxOptions(options! as FirefoxOptions)
.withCapabilities(capabilities)
// As an alternative to this method, you may also set the SELENIUM_REMOTE_URL environment variable.
// TODO: magic constant.
.usingServer(remoteDriverConnectionStr)
.build();
gT.sOrig.driver
.getSession()
.then(res => {
const sid = gIn.remoteDriverUtils.saveSid(res.getId());
gIn.tracer.msg3(`Saved session id: ${sid}`);
})
.catch(e => {
gIn.logger.exception('Error at getSession: ', e);
});
}
// ==============================
// TODO:
// Using undocumented property to trace all selenium commands.
// let executorRef = gT.sOrig.driver.executor_;
// executorRef.executeOrig = executorRef.execute;
// executorRef.execute = function (command) {
// gIn.tracer.trace3('COMMAND: ' + command.getName());
// // TODO: tracing, let params = command.getParameters();
// return executorRef.executeOrig(command)
// .then(function (res) {
// // TODO: tracing, command result.
// return res;
// })
// .catch(function (e) {
// // TODO: tracing, command fail.
// throw e;
// });
// };
// ==============================
} else {
// Temporary driver
gT.sOrig.driver = new gT.sOrig.wdModule.Builder()
.forBrowser(gT.cLParams.browser)
.setChromeOptions(options! as ChromeOptions)
.setFirefoxOptions(options! as FirefoxOptions)
.withCapabilities(capabilities)
.build();
}
gT.sOrig.logs = gT.sOrig.driver.manage().logs();
if (gT.cLParams.useRemoteDriver) {
return;
}
// Trying to fix chromedriver issue 817 by delay.
// https://bugs.chromium.org/p/chromedriver/issues/detail?id=817#c21
return gT.u.promise.delayed(gT.engineConsts.defaultDelayAfterDriverCreate);
},
});
}
export function sleep(ms: number, enableLog?: EnableLog) {
return gIn.wrap({
msg: `Sleep ${ms} ms ... `,
enableLog,
act: () => gT.u.promise.delayed(ms, true),
});
}
const stupidSleep = 400;
/**
* This function creates function for stupid sleep.
* It is stupid sleep instead of smart waiting for something.
*/
export function getStupidSleepFunc() {
return function() {
return sleep(stupidSleep, false);
};
}
export function quit(enableLog?: EnableLog) {
if (gT.cLParams.ejExplore) {
gIn.tracer.msg3('quit: ejExplore, no quit');
return Promise.resolve('ejExplore, no quit');
}
// if (typeof enableLog === 'undefined' && !gT.config.browserProfileDir) {
// enableLog = false;
// }
if (gIn.sharedBrowserInitiated) {
gIn.tracer.msg3('quit: Shared browser, no quit');
return Promise.resolve('Shared browser, no quit');
}
return gIn.wrap({
msg: 'Quiting ... ',
enableLog,
act: () =>
gT.sOrig.driver.quit().then(() => {
gIn.tracer.msg3('Quit: Driver is deleted');
delete gT.sOrig.driver;
}),
noConsoleAndExceptions: true,
});
}
export function quitIfInited() {
if (gT.cLParams.ejExplore) {
gIn.tracer.msg3('quitIfInited: ejExplore, no quit');
return Promise.resolve('ejExplore, no quit');
}
if (gT.sOrig.driver) {
gIn.tracer.msg3('quitIfInited: before quit call');
return gT.sOrig.driver.quit().then(() => {
delete gT.sOrig.driver;
gIn.tracer.msg3('quitIfInited: Driver is deleted');
});
}
gIn.tracer.msg3('quitIfInited: no driver, no quit');
return Promise.resolve('No driver, no quit');
}
export function printSelDriverLogs(minLevel: number) {
return gT.sOrig.logs.get(gT.sOrig.driverLogType).then(entries => {
gIn.tracer.msg3('Start of printSelDriverLogs');
for (const entry of entries) {
if (
entry.level.value >= minLevel &&
!entry.message.includes(
'This version of ChromeDriver has not been tested with Chrome version'
)
) {
const logStr = `SEL.DR.LOG: ${entry.level.name} (${entry.level.value}), Message:\n ${entry.message}`;
gIn.logger.logln(logStr);
}
}
gIn.tracer.msg3('End of printSelDriverLogs');
});
}