Nightwatch: Override Function in Page Object - javascript

I have created a page object model in Nightwatch but I would like to override some functions for customization. How would I achieve that?
module.exports = {
url: 'http://localhost:63916/Login/Login',
commands: [{
navigateToImportBatch() {
this
.click('#importManager')
.click('#importBatch')
return this.api;
}
};
How can I override the navigateToImportBatch function? Thanks.

Override globally:
// your current module to override, e.g. loginPageModel.js
let module = {
url: 'http://localhost:63916/Login/Login',
commands: [{
navigateToImportBatch() {
this.click('#importManager')
.click('#importBatch');
return this.api;
}
}]
};
module.exports = module;
And then define a new module, override whatever commands you need to and export it.
// loginOverride.js
let LoginOverride = require('./loginPageModel'); // whatever the path to your module is called
LoginOverRide.commands[0].navigateToImportBatch = function() {
// your new implementation
}
module.exports = LoginOverride;
Then simply import the module that overrides the base implementation in your step definition/s.
let LoginModel = require('./loginOverride');
// use as normal
Alternately you can use the same strategy in a step definition without defining a new page model, and just override the implementation from the step definition.

Related

NodeJS: How to delay a module's resolution due to the dependencies on that module

Suppose the following scenario:
We have a class that handles a Mongoose connection as below:
export interface IInstance {
name: string;
instance: Mongoose.Mongoose;
}
export default class MongoHandler {
public static instances: IInstance[] = [{
name: 'default',
instance: null,
}];
// Connect to mongo instance and add it to the instances array
public static async connect(name: string, uri: string, options?: object): Promise<void> {
const instance: Mongoose.Mongoose = await Mongoose.connect(uri, options);
const newInstance: IInstance = {
name,
instance,
};
MongoHandler.instances.push(newInstance);
}
// Returns the instance based on the name of instance
public static getInstance(name: string = 'default'): Mongoose.Mongoose {
return this.instances.find(instance => instance.name === name).instance;
}
}
The other module called CarModel is using getInstance() method for creating a model:
export interface ICar {
name: string;
}
const carSchema = new Mongoose.Schema<ICar>(
{
name: {
type: String,
required: true,
},
}
);
const carModel = MongoHandler.getInstance('default').model<ICar>('Car', carSchema, 'Cars');
export default carModel;
We are using carModel in a module called CarController.
In index.ts we are calling these two modules as below:
import
const app = new App(
[
MongoHandler.connect('default', process.env.MONGO_URI),
],
[
new CarController(),
]
);
App is a class for handling express bootstrapping (can be ignored).
While running this code MongoHandler.getInstance('default') is undefined because of the order of dependency resolution (I think)! And resolving MongoHandler.getInstance('default') is followed by MongoHandler.connect() which should be reversed.
How can I solve this?
Best regards
I think there are 2 issues at play here, neither of them having to do with module resolution (which will work just fine as you don't have any circular dependencies).
array.prototype.find returns the FIRST match found, you instantiate instances array with an object that matches the name default, but has no instance. When you connect, you add another object with the name default, but this will be second in the list, thus find will return the original object, which has its instance object set as null.
I would advice removing this default empty instance object for error and code clarity.
your connect function makes use of async-await. But you never await your connect function, thus not guaranteeing that your new connection instance has been made before you are calling getInstance inside of your carController. You should catch the Promise returned by the connect function and await it. If you do not want to delay your CarController instantiation, you can use save this Promise in the MongoHandler and return it with some init function that you call inside of the CarController to make sure the connect has been resolved.

In ES6 synthax, how can I do named export using variable key?

I have an Object I dont know the whole content.
I want to produce a named export of everything, as a reminder, this is a named export :
export const myFunction = () => {};
How can I iterate on the keys of my object, and export everything as named ?
Something like this does not work because I am trying to initialize module.exports:
const cfgEnv = require(`./${process.env.REACT_APP_ENV}`);
Object.keys(cfgEnv).forEach((key) => {
if (!module.exports) {
module.exports = {};
}
module.exports[key] = cfgEnv[key];
});
You can use
const cfgEnv = require(`./${process.env.REACT_APP_ENV}`);
module.exports = cfgEnv;
it will work like
module.exports = {
foo: 'bar'
}
I want to produce a named export using variable key?
You cannot. ES6 module exports must be static.
I am trying to initialize module.exports
That's not ES6 module syntax, that's a CommonJs module. But doing so is relatively trivial using Object.assign:
module.exports = Object.assign({}, require(`./${process.env.REACT_APP_ENV}`));

TypeScript: declare a variable that is a function named "new"

Let's say I want to write TypeScript definitions of a modules where it's JavaScript equivalent is the following:
var service = {};
service.new = function (name, options) {
console.log('Ive been called!');
};
module.exports = service;
How shall I declare it? I can't find a way to declare this property called new on the service as new is a reserved keyword but still this JavaScript code works and should be definable in a .d.ts file.
My last failed attempt was
export = ModuleName;
export as namespace ModuleName;
declare var instance: ModuleName.StaticInstance;
declare namespace ModuleName {
interface StaticInstance {
new(name: string, options: ModuleName.Options): NewService;
}
interface NewService {
someMethod()...
}
interface Options {
option1: number;
...
}
}
Any hints?
In certain contexts you can quote identifier names:
interface MyModule {
"new"(name: string, options: Options): NewService;
}
declare const m: MyModule;
export = m;

Aurelia pass configuration to plugin or feature

I want to pass some configuration information into my aurelia feature but I am not sure how. I found no documentation on how do this in the aurelia docs.
My Feature
Main.js
.feature('aurelia-scrollbar', config => {
// I want to pass an object along this
config.foo = { bar: 'yay' }
})
Index.js
export function configure(config) {
config.globalResources('./scrollbar');
}
Scrollbar.js
import Scrollbar from 'smooth-scrollbar';
import 'smooth-scrollbar/dist/smooth-scrollbar.css!';
export class ScrollbarCustomAttribute {
static inject = [Element];
constructor(element) {
this.element = element;
}
attached() {
Scrollbar.init(this.element); // I want to use the passed configuration option here
}
}
The feature method (and plugin method) will accept your feature-specific configuration as a parameter:
main.js
let scrollbarConfig = { foo: 'bar' };
aurelia.use
.standardConfiguration()
.feature('aurelia-scrollbar', scrollbarConfig);
In your feature's configure method, register the config object in the container.
aurelia-scrollbar/index.js
export function configure(frameworkConfiguration, scrollbarConfig) {
frameworkConfiguration.globalResources('./scrollbar');
frameworkConfiguration.container.registerInstance('scrollbar-config', scrollbarConfig);
}
Anything that depends on the configuration can use the container to retrieve it:
aurelia-scrollbar/scrollbar.js
#inject(Element, 'scrollbar-config')
export class Scrollbar {
constructor(element, scrollbarConfig) {
...
}
...
}
GitHub issue to add this information to the Aurelia documentation: https://github.com/aurelia/framework/issues/570

NodeJs: How to export all the modules and variables in a Javascript file?

How can I export all the modules and variables present in a Javascript file using NodeJS. Suppose i have a .js file with 20 functions and 20 variables and i need to export all of the functions and variables at once and not one by one. How can i achieve this?
You can't. You must explicitly name them, in some way.
If Amberlamps' answer is not possible (you want them at the base level), you could still do:
module.exports = {
functionA: function () {
// TODO
},
functionB: function () {
// TODO
},
// the rest
};
How about this:
exports.MyApp = {
functionA: function() {
// TODO
},
functionB: function() {
// TODO
}
};

Categories