@assert-equals/dappdriver
Version:
DappDriver is an e2e testing framework designed for testing decentralized applications (dApps) using MetaMask, Rainbow or Zerion
341 lines (340 loc) • 10.7 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DappDriver = void 0;
const headless_wallet_1 = require("@assert-equals/headless-wallet");
const constants_1 = require("../constants");
const page_1 = require("../page");
const playwright_factory_1 = require("../playwright/playwright-factory");
const webdriver_factory_1 = require("../webdriver/webdriver-factory");
/**
*
*
* @export
* @class DappDriver
*/
class DappDriver {
static instance = null;
domain;
extension;
isDisposed;
driver;
page;
frame;
framework;
wallet;
/**
* Creates an instance of DappDriver.
* @param {string} domain
* @param {Framework} framework
* @param {Driver} driver
* @memberof DappDriver
*/
constructor(domain, framework, driver) {
this.domain = domain;
this.framework = framework;
this.driver = driver;
}
static get Instance() {
return this.instance;
}
static set Instance(value) {
this.instance = value;
}
get Framework() {
return this.framework;
}
get Disposed() {
return this.isDisposed;
}
set Disposed(value) {
this.isDisposed = value;
}
get Driver() {
return this.driver;
}
set Driver(value) {
this.driver = value;
}
get Domain() {
return this.domain;
}
get Extension() {
return this.extension;
}
set Extension(value) {
this.extension = value;
}
get Page() {
return this.page;
}
set Page(value) {
this.page = value;
}
get Frame() {
return this.frame;
}
set Frame(value) {
this.frame = value;
}
get Wallet() {
return this.wallet;
}
set Wallet(value) {
this.wallet = value;
}
static async create(domain, framework, browser, arg4, options) {
let tPage = null;
options = options || { proxy: false, extension: { wallet: null, path: null, seed: null } };
options.proxy = options.proxy ?? false;
options.extension = options.extension ?? { wallet: null, path: null, seed: null };
if (typeof arg4 === 'function') {
tPage = arg4;
}
else if (typeof arg4 === 'object') {
options = arg4;
}
let driver = null;
const session = new DappDriver(domain, framework, driver);
DappDriver.instance ??= session;
await DappDriver.loadExtensionModule(options);
await DappDriver.install(options);
driver = await DappDriver.build(framework, browser, options);
DappDriver.Instance.Driver = driver;
let page = null;
if (framework === constants_1.PLAYWRIGHT) {
page = driver.pages()[0];
DappDriver.Instance.Page = page;
}
await DappDriver.setupWallet(options);
await this.open(domain);
if (tPage === null)
return;
const newPage = await this.getPage(tPage);
return newPage;
}
/**
*
*
* @private
* @static
* @param {Framework} framework
* @param {Browser} browser
* @param {BrowserOptions} options
* @return {*} {Promise<Driver>}
* @memberof DappDriver
*/
static async build(framework, browser, options) {
let driver;
if (framework === constants_1.PLAYWRIGHT) {
driver = await new playwright_factory_1.PlaywrightFactory().build(browser, options);
}
else if (framework === constants_1.WEBDRIVER) {
driver = await new webdriver_factory_1.WebDriverFactory().build(browser, options);
}
else {
throw new Error('Unsupported framework: ' + framework);
}
return driver;
}
/**
*
*
* @private
* @static
* @param {BrowserOptions} options
* @return {*} {Promise<void>}
* @memberof DappDriver
*/
static async install(options) {
try {
switch (options.extension.wallet) {
case constants_1.METAMASK:
case constants_1.METAMASK_FLASK:
case constants_1.RAINBOW:
case constants_1.ZERION: {
const initCwd = process.env.INIT_CWD;
const cwd = process.cwd();
const downloadDir = `${initCwd || cwd}/${constants_1.NODE_MODULE_DIR}`;
const path = await DappDriver.Instance.Extension.install(downloadDir, options.extension.version);
options.extension.path ??= path;
break;
}
}
}
catch (error) {
throw new Error('Failed to install extension: ' + error);
}
}
/**
*
*
* @private
* @static
* @param {BrowserOptions} options
* @return {*} {Promise<void>}
* @memberof DappDriver
*/
static async loadExtensionModule(options) {
try {
switch (options.extension.wallet) {
case constants_1.METAMASK:
case constants_1.METAMASK_FLASK:
case constants_1.RAINBOW:
case constants_1.ZERION: {
const extensionModule = await Promise.resolve(`${`../${options.extension.wallet}`}`).then(s => __importStar(require(s)));
DappDriver.Instance.Extension = extensionModule.default;
break;
}
}
}
catch (error) {
throw new Error('Failed to load extension module: ' + error);
}
}
/**
*
* Schedules a command to navigate to a new URL
* @private
* @static
* @param {string} url
* @return {*} {Promise<void>}
* @memberof DappDriver
*/
static async open(url) {
if (DappDriver.Instance.Framework === constants_1.PLAYWRIGHT) {
const page = DappDriver.Instance.Page;
await page.goto(url);
}
else if (DappDriver.Instance.Framework === constants_1.WEBDRIVER) {
await DappDriver.Instance.Driver.get(url);
}
}
/**
*
*
* @private
* @static
* @param {BrowserOptions} options
* @return {*} {Promise<void>}
* @memberof DappDriver
*/
static async setupWallet(options) {
try {
switch (options.extension.wallet) {
case constants_1.METAMASK:
case constants_1.METAMASK_FLASK:
case constants_1.RAINBOW:
case constants_1.ZERION:
DappDriver.Instance.Wallet = options.extension.wallet;
await DappDriver.Instance.Extension.setup(options.extension.seed);
break;
case constants_1.HEADLESS:
DappDriver.Instance.Wallet = constants_1.HEADLESS;
if (DappDriver.Instance.Framework === constants_1.PLAYWRIGHT) {
const page = DappDriver.Instance.Page;
await (0, headless_wallet_1.setupHeadlessWallet)({ page, port: options.extension.port });
}
else if (DappDriver.Instance.Framework === constants_1.WEBDRIVER) {
const driver = DappDriver.Instance.Driver;
await (0, headless_wallet_1.setupHeadlessWallet)({ driver });
}
break;
}
}
catch (error) {
await this.dispose();
throw new Error('Error setting up wallet: ' + error);
}
}
/**
*
*
* @static
* @template TPage
* @param {new () => TPage} page
* @return {*} {Promise<TPage>}
* @memberof DappDriver
*/
static async getPage(page) {
const newPage = new page();
if (newPage instanceof page_1.PageObject) {
await newPage.waitForTitle();
await newPage.waitForURL();
}
return newPage;
}
/**
*
* Schedules a command to quit the current session
* @static
* @return {*} {Promise<void>}
* @memberof DappDriver
*/
static async dispose() {
if (DappDriver.Instance === null) {
return;
}
if (DappDriver.Instance.Framework === constants_1.PLAYWRIGHT) {
await DappDriver.Instance.Driver.close();
}
else if (DappDriver.Instance.Framework === constants_1.WEBDRIVER) {
await DappDriver.Instance.Driver.quit();
}
DappDriver.instance = null;
}
/**
*
* Schedules a command to make the driver sleep for the given amount of time
* @static
* @param {number} duration
* @return {*} {Promise<void>}
* @memberof DappDriver
*/
static async sleep(duration) {
await new Promise((resolve) => setTimeout(resolve, duration));
}
/**
*
* Schedule a command to take a screenshot
* @static
* @return {*} {Promise<string>}
* @memberof DappDriver
*/
static async takeScreenshot() {
if (DappDriver.Instance === null) {
return;
}
let screenShot;
if (DappDriver.Instance.Framework === constants_1.PLAYWRIGHT) {
screenShot = (await DappDriver.Instance.Page.screenshot()).toString('base64');
}
else if (DappDriver.Instance.Framework === constants_1.WEBDRIVER) {
screenShot = await DappDriver.Instance.Driver.takeScreenshot();
}
return screenShot;
}
}
exports.DappDriver = DappDriver;