UNPKG

@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
"use strict"; 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;