Protractor - pass value from one describe /IT block to another - protractor

I have two portals.one is admin and one is for end user. I create product in admin and create order in eu.
I have created product in one describe block.Now, i want to save the product name and next .js file. How this can be achieved?
below is the code to create a product. how to save the product name and pass it to other js file?
describe('Should Login to admin and create a product', function() {
it('should create a dynamic product ', function(done) {
loginPage.login();
productPage.createProduct();
productCreatePage.productDynamicGeneral();
productCreatePage.productDocumentTemplate();
productCreatePage.stores();
//productCreatePage.PopUpMessage(dynamicProductCreate);
productCreatePage.configurationWithDefaultProfile();
});
});

You can achieve this using NodeJSs global variables but obviously your tests will need to be executed in the correct order.
create gbl var.js
describe('Global Var', () => {
it('will be created', async () => {
global.gbl_productName = 'New Global Variable Value';
});
});
Use gbl var
describe('Global Var', () => {
it('will be used', async () => {
console.log(gbl_productName);
});
});

Related

How can I mock aws-sdk with jest?

I am trying to mock aws-sdk with jest. Actually I only care about one function. How can I do this? I have read the docs about mocking classes with jest, but the docs are complicated and I don't quite understand them.
Here is my best attempt:
handler.test.js
'use strict';
const aws = require('aws-sdk');
const { handler } = require('../../src/rotateSecret/index');
jest.mock('aws-sdk');
const event = {
SecretId: 'test',
ClientRequestToken: 'ccc',
Step: 'createSecret',
};
describe('rotateSecret', () => {
it.only('should not get or put a secret', async () => {
aws.SecretsManager.mockImplementation(() => ({
getSecretValue: () => ({}),
}));
expect.assertions(1);
await handler(event);
// You can see what I am trying to do here but it doesn't work
expect(aws.SecretsManager.getSecretManager).not.toHaveBeenCalled();
});
});
handler.js
exports.handler = async (event) => {
const secretsManager = new aws.SecretsManager();
const secret = await secretsManager.describeSecret({ SecretId: event.SecretId }).promise();
if (someCondition) {
console.log("All conditions not met");
return;
}
return secretsManager.getSecretValue(someParams)
};
Okay so the way I would approach this is as follows:
AWS-SDK Mock
Create an actual mock for aws-sdk and put it in __mocks__/aws-sdk.js file at the root of your project
// __mocks__/aws-sdk.js
class AWS {
static SecretsManager = class {
describeSecret = jest.fn(() =>{
return { promise: ()=> Promise.resolve({ ARN: "custom-arn1", Name: "describeSec" })}
});
getSecretValue = jest.fn(() =>{
return {promise: ()=> Promise.resolve({ ARN: "custom-arn2", Name: "getSecretVal" })
});
};
}
module.exports = AWS;
I have used static before SecretsManager because AWS class is never instantiated yet it wants access to SecretsManager class.
Inside SecretsManager, I have defined 2 functions and stubbed them using jest.fn.
Now same stuff as you have done in your test file:
jest.mock('aws-sdk');
How to Test
To test if your mock functions are called, thats the tricky part (so i will detail that at the end of this post).
Better approach would be to assert against the end result of your main function after all processing is finished.
Assertions
Back in your test file, I would simply invoke the handler with the await (as you already have) and then assert against the final result like so:
// test.js
describe("rotateSecret", () => {
it.only("should not get or put a secret", async () => {
const event = {name:"event"};
const result = await handler(event);
expect(result).toEqual("whatever-your-function-is-expected-to-return");
});
});
Testing Secret Manager's function invocations
For this you will need to tweak your main handler.js file itself and will need to take out invocation of secrets Manager from the main function body like so:
const secretsManager = new aws.SecretsManager(); // <---- Declare it in outer scope
exports.handler = async (event) => {
const secret = await secretsManager
.describeSecret({ SecretId: event.SecretId })
.promise();
if (someCondition) {
console.log("All conditions not met");
return;
}
return secretsManager.getSecretValue(someParams);
};
Then back in your test.js file, you will need to similarly declare the SecretsManager invocation before you initiate your handler function like so:
//test.js
describe("rotateSecret", () => {
const secretsManager = new aws.SecretsManager(); // <---- Declare it in outer scope
it.only("should not get or put a secret", async () => {
const event = {name:"event"};
await handler(event);
// Now you can make assertions on function invocations
expect(secretsManager.describeSecret).toHaveBeenCalled();
// OR check if passed args were correct
expect(secretsManager.describeSecret).toHaveBeenCalledWith({
SecretId: event.SecretId,
});
});
});
This will allow you to make assertions on function invocation as well the args that were passed.
The reason I declare it outside function scope is to tell Jest that secretsManager should be existing somewhere in global scope and it should be used from there.
Previously, we had it declared inside the function scope, so Jest would invoke it but we weren't able to get access to it.
We couldn't directly reference it like this AWS.SecretsManager.getSecretManager because getSecretManager method is only available after you instantiate the SecretsManager class (and even if you did that, you will get a new instance of the class which won't help with any assertions).
Downside of __mocks__/aws.js fake module
Obvious issue is - you are stubbing the function on every single call and maybe you won't want that.
Perhaps you only want to stub it out once for a specific test but for the rest of them you want it to run normal.
In that case, you should not create __mocks__ folder.
Instead, create a one-time fake BUT make sure your SecretsManager invocation is in the outside scope in your test file as before.
//test.js
const aws = require("aws-sdk");
describe("rotateSecret", () => {
// Declare it in outer scope
const secretsManager = new aws.SecretsManager();
it.only("should not get or put a secret", async () => {
const event = {name:"event"};
// Create a mock for this instance ONLY
secretsManager.describeSecret = jest.fn().mockImplementationOnce(()=>Promise.resolve("fake-values"));
await handler(event);
expect(secretsManager.describeSecret).toHaveBeenCalled();
expect(secretsManager.describeSecret).toHaveBeenCalledWith({
SecretId: event.SecretId,
});
});
});

FindOne never gets executed Meteor js

I have been on this for a while. The problem with is is that this line of code never get executed let userSchool = SchoolDb.findOne({slug: Session.get('ReceivedSlug')}); When I logged on the console I see the the slug is dynamic as it is suppose to be pull the record from the db. What am I to do right?
The oncreated template
Template.view.onCreated(function () {
Session.set('ReceivedSlug', FlowRouter.getParam('myslug'));
this.autorun(function () {
Meteor.subscribe('SingleSchool', Session.get('ReceivedSlug'));
});
});
The helper function
singleSchool: function () {
if (Meteor.userId()) {
console.log('reactive this ---- ' +Session.get('ReceivedSlug'));
let userSchool = SchoolDb.findOne({slug: Session.get('ReceivedSlug')});
if (!userSchool) {
Bert.alert('School not present', 'danger', 'growl-top-right');
} else {
console.log('school name ----' +userSchool.slug);
return userSchool;
}
}
},
Can you please check whether the subscription has fetched data. Also console out inside publish that whether data gets published when slug changed.
Use below code to check if subscription is working
Meteor.subscribe('SingleSchool', Session.get('ReceivedSlug'), {
onReady: function(){
console.log(SchoolDb.find({}).fetch());
}
});

Slim route groups not working as expected

In my code I am doing something very similar to the following (from the slim docs). My expected behaviour is that groups restrict the route scope to within that group e.g. /library/books is not the same as /books. However, I'm finding in my code that the group method is not restricting the route as expected and for example the route for /admin/tours is being called even when I go to /tours. Is there something I am missing? The docs for group on the homepage (www.slimframework.com) of the slim website are different from the documentation website (http://docs.slimframework.com/routing/groups/).
$app = new \Slim\Slim();
// API group
$app->group('/api', function () use ($app) {
// Library group
$app->group('/library', function () use ($app) {
// Get book with ID
$app->get('/books/:id', function ($id) {
});
// Update book with ID
$app->put('/books/:id', function ($id) {
});
// Delete book with ID
$app->delete('/books/:id', function ($id) {
});
});
});
Further example
$app->group( '/admin', function () use ( $app , $twig) {
$app->get('/tours', function() use ($app){
print_r('do tours admin');
});
});
$app->get('/tours', function() use ($app){
print_r('do tours');
});
my behaviour is that /tours is still routing to /admin/tours
It seems like a bit of a simple solution but ordering the registering of the /tours route before the /admin/tours route sorted it.

Using Data Objects while E2E testing with Protractor

So a coworker and I were discussing making a data object for our e2e tests. From my understanding about data objects they are used for decoupling your test suites. For example, my first test suite is to create an account and to test if the fields are valid and the second test suite logins into the account and does its own tests. I am told it is good to use data objects (not a page object) just incase the first test suite fails when making an account. That way we can use the data object in the second test suite to create a new user just for testing login. My problem is that if my first test suite fails at making an account, why would creating an account in my second test suite pass? Whatever error I get in the First test suite, I should also get in the second test suite right? I have many more questions about data objects and how to use them. I was wondering if someone could explain data objects and how to use/write one.
/***
Test Data Object
***/
var Member = function() {
var unixTime = String(Math.round(new Date()/1000));
this.username = "TestAccount" + unixTime;
this.email = this.username + "#gmail.com";
this.password = "password";
};
Member.prototype.create = function () {
var signup = new signupPage.Signup();
signup.getPage();
signup.memberAs(this.username, this.email, this.password);
};
Member.prototype.login = function () {
var login = new loginPage.Login();
login.getPage();
login.memberAs(this.username, this.password);
};
Member.prototype.logout = function () {
// k.logoutMember();
};
exports.Member = Member;
This is the data object my coworker wrote. We haven't finished writing the tests because we stopped to think about it more, but here are the tests we have so far.
var chai = require('chai');
var chaiAsPromised = require("chai-as-promised");
var expect = chai.expect;
var member = require('./lib/test-data');
chai.use(chaiAsPromised);
describe.only('Member Account Settings and Information', function() {
before(function () {
member.create();
});
before.each(function() {
member.login();
});
describe('My Account', function () {
it('Logging in should enable the "My Account" link.', function() {
member.login();
});
it('Clicking on "My Account" should expand the account options', function() {
});
});
I use hashes for my data objects. Here's an example from my protractor_example code on GitHub.
Given a data file:
var UserData = function() {
this.testUser = {'username': 'test', 'password': 'test'};
};
module.exports = new UserData();
Then the spec...
describe ('non-angular login test', function() {
var loginPage = require('../pages/nonAngularLoginPage.js');
var userData = require('../data/userData.js');
it('should goto friend pages on successful login', function() {
loginPage.loginAs(userData.testUser);
expect(browser.getTitle()).toContain('Angular JS Demo');
});
});

How to add custom javascript code to validate field in contacts module in sugarcrm

I want custom code to be made on onblur of first_name field in sugarcrm.
The code should also be upgrade safe.
Please help!
Copy modules/Contacts/metadata/editviewdefs.php
into
custom/modules/Contacts/metadata/editviewdefs.php
(if it does not already exist. If so, use the existing one)
All your changes in this file are upgrade safe. Now open your new file, and you'll see one big array containing everything that's in the EditView of the Contacts-module.
Add the following inside the "templateMeta" array, for instance, right after "form".
'includes'=> array(
array('file'=>'custom/modules/Contacts/EditView.js'),
),
This includes the file custom/modules/Contacts/EditView.js, in which you are free to write all the javascript you feel like!
Remember to do a Quick Repair & Rebuild when you are done.
I don't know which version of SugarCRM you uses, but in SugarCRM 7, the following works:
Create a file 'record.js' in /custom/modules/Contacts/clients/base/views/record/. In that file, you can add custom validation.
Some code you could use is:
({
extendsFrom: 'YourModuleRecordView',
initialize: function (options) {
app.error.errorName2Keys['field_error'] = 'This is an error message';
this._super('initialize', [options]);
this.model.addValidationTask('check_field', _.bind(this._doValidateField, this));
},
_doValidateField: function(fields, errors, callback) {
if (this.model.get('myField') .... ) {
errors['myField'] = errors['myField'] || {};
errors['myField'].field_error = true;
}
callback(null, fields, errors);
}
});
Don't forget to change the fields names like you named them!
This result is only for edit mode. To add this validation to the creation mode, add the file 'create_actions.js' to /custom/modules/Contacts/clients/base/views/create_actions/
Enter the folling code in your 'create_actions.js':
({
extendsFrom: 'CreateActionsView',
initialize: function (options) {
app.error.errorName2Keys['field_error'] = 'Thsis is an error message';
this._super('initialize', [options]);
this.model.addValidationTask('check_field', _.bind(this._doValidateField, this));
},
_doValidateField: function(fields, errors, callback) {
if (.....) {
errors['myField'] = errors['myField'] || {};
errors['myField'].field_error = true;
}
callback(null, fields, errors);
}
});
Perform a repair/rebuild when you added this files with the right code.
You can customize this code to your own needs.