/** * @class stpo * @singleton * `stpo` is a reserved namespace in which a project's registered PageObjects will be available. * While you can use the {@link ST.PageObject} Manager directly to retrieve instances of individual PageObjects, * the `stpo` object provides a more convenient way to access the PageObject instances. * * // retrieve PageObject instance from Manager * var login = ST.PageObject.get('login'); * // alternatively, retrieve PageObject instance from `stpo` object * var login = stpo.login; */stpo = {}; // eslint-disable-line /** * @class ST.PageObject * The PageObject Manager is a cache of registered PageObjects. The Manager provides a number of methods for interating * with PageObjects for use within tests. */ST.pageobject.Manager = ST.PageObject = { _pageObjects: {}, _scopeName: 'stpo', /** * @method register * Registers a PageObject with the global Manager. Once registered, the PageObject can be retrieved via ST.PageObject.get. * @param {String/Function} pageObject The PageObject (either type or class) to register with the Manager's cache. NOTE: * PageObjects are auto-registered with the cache when the class is defined, so there is typically no need to call this * method directly */ register: function (pageObject, overwrite) { var objs = pageObject, i, isDupe, type, obj, instance, name; if (!objs) { throw new Error('No PageObject was provided for registration'); } if (!ST.isArray(objs)) { objs = [objs]; } for (i=0; i<objs.length; i++) { obj = objs[i]; // accept string or constructor obj = typeof obj === 'string' ? ST.clsFromString(obj) : obj; // try to instantiate an instance try { instance = new obj(); } catch (e) { throw new Error('There was an error creating the page object:\n ' + e); } // if instantiation was successful, get the type of the page object type = instance.getType(); if (!overwrite) { isDupe = !!this._pageObjects[type]; if (isDupe) { throw new Error('The PageObject provided (' + type + ') would duplicate an already-registered PageObject'); } } name = instance.getName(); // if we made it this far, register the page object this._pageObjects[type] = { instance: instance, type: type, name: name, clsName: instance.$className }; // add to global scope for shorthand purposes window[this._scopeName][name] = instance; } }, /** * @method deregisterAll * Removes all registered PageObjects from the Manager's registration cache */ deregisterAll: function () { var objs = this._pageObjects, key; for (key in objs) { this.deregister(key, true); } }, /** * @method deregister * Removes a PageObject from the Manager's registration cache * @param {String/Object/Function...} pageObject The PageObject to remove from the registration cache. */ deregister: function (pageObject, ignoreErrors) { var type, instance, hasExistenceError = false, ignore = typeof ignoreErrors === 'undefined' ? false : !!ignoreErrors; if (!pageObject) { throw new Error('No PageObject was provided for deregistration'); } if (pageObject === 'basepageobject') { if (!ignoreErrors) { throw new Error('Base PageObject cannot be deregistered'); } return false; } if (typeof pageObject === 'string') { instance = this._findByName(pageObject); type = instance && instance.instance.getType(); } else if (typeof pageObject === 'object' && pageObject.$isPageObject) { type = pageObject.getType(); } else if (typeof pageObject === 'function') { type = pageObject.prototype.type; } if (type) { instance = this.get(type); if (!instance) { hasExistenceError = true; } else { // remove from internal cache delete this._pageObjects[type]; // remove from global scope to be a good citizen delete window[this._scopeName][instance.getName()]; } } else { hasExistenceError = true; } if (hasExistenceError && !ignore) { throw new Error('The requested PageObject could not be deregistered because it does not exist in the registration cache'); } }, /** * @method get * Returns a PageObject from the Manager's registration cache by type, name, or className * @param {String} type The "type" of the PageObject to retrieve. The name or className of the PageObject may also be used * @return {Object} Registered PageObject instance */ get: function (type) { var obj = this._pageObjects[type]; if (!type) { throw new Error('No "type" provided for PageObject Manager lookup'); } if (!obj) { obj = this._findByName(type); } return obj && obj.instance || null; }, /** * @method getType * @private * Returns a PageObject from the Manager's registration cache by type, name, or className * @param {String} name The PageObject type, name, or className by which to locate the registered PageObject * @return {Object} */ _findByName: function (name) { var pageObjects = this._pageObjects, obj, key, match; for (key in pageObjects) { obj = pageObjects[key]; if (key === name || obj.name === name || obj.clsName === name) { match = obj; break; } } return match || null; }};