How do I keep writing in the same JSON file within cypress? - testing

I'm currently setting up a test scenario that allows me to create a random email, and I would like to do more series of tests and keep writing on the same JSON file instead of overwriting what I already sent to the JSON files. Meaning that I would like to use the same JSON file to save all of the emails that I created with my tests.
Does anyone knows a better way to do this?
Cypress.Commands.add("form", ()=> {
// fill-out form
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
const fullName = 'MockaData Testing'
const email = makeid(6) + "#aharo.com";
console.log(makeid(5));
cy.get('#full_name')
.type(fullName)
cy.get('#company')
.type('Testing')
cy.get('#phone_number')
.type('2022569878')
cy.get('#email')
.type(email).writeFile('cypress/fixtures/users.json', {name: fullName, email: email})
cy.get('#password')
.type('Abcd1234')
// click submit
cy.get(".app-submit-btn-text", { multiple: true }).click()
})

To achieve this you have to use { flag: 'a+' } (cypress docs). This will append the contents at the end of the file instead of overwriting it.
cy.writeFile('cypress/fixtures/users.json', {name: fullName, email: email}, {flag: 'a+'})

Related

How to add new fileds/values to line widgets in Barcode mobile view in Odoo14 EE?

Hi i am trying to add two new fields to the Barcode mobile view. I went through the default js code of odoo, but didn't find a way to add my custome fields to it.
Here is the default code
stock_barcode/static/src/js/client_action/lines_widget.js
init: function (parent, page, pageIndex, nbPages) {
this._super.apply(this, arguments);
this.page = page; #don't know where this argument page coming from in argument list.
this.pageIndex = pageIndex;
this.nbPages = nbPages;
this.mode = parent.mode;
this.groups = parent.groups;
this.model = parent.actionParams.model;
this.show_entire_packs = parent.show_entire_packs;
this.displayControlButtons = this.nbPages > 0 && parent._isControlButtonsEnabled();
this.displayOptionalButtons = parent._isOptionalButtonsEnabled();
this.isPickingRelated = parent._isPickingRelated();
this.isImmediatePicking = parent.isImmediatePicking ? true : false;
this.sourceLocations = parent.sourceLocations;
this.destinationLocations = parent.destinationLocations;
// detect if touchscreen (more complicated than one would expect due to browser differences...)
this.istouchSupported = 'ontouchend' in document ||
'ontouchstart' in document ||
'ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0;
},
In _renderLines function,
_renderLines: function () {
//Skipped some codes here
// Render and append the lines, if any.
var $body = this.$el.filter('.o_barcode_lines');
console.log('this model',this.model);
if (this.page.lines.length) {
var $lines = $(QWeb.render('stock_barcode_lines_template', {
lines: this.getProductLines(this.page.lines),
packageLines: this.getPackageLines(this.page.lines),
model: this.model,
groups: this.groups,
isPickingRelated: this.isPickingRelated,
istouchSupported: this.istouchSupported,
}));
$body.prepend($lines);
for (const line of $lines) {
if (line.dataset) {
this._updateIncrementButtons($(line));
}
}
$lines.on('click', '.o_edit', this._onClickEditLine.bind(this));
$lines.on('click', '.o_package_content', this._onClickTruckLine.bind(this));
}
In the above code, you can see this.page.lines field, i need to add my custom two more fields.
Actually it's dead-end for me.
Any solution?

Unable to Upload file(jpeg, png, pdf etc) into File cabinet / custom record through online HTML form in NetSuite

Issue:
I'm facing issue while making a custom record of the online form which I'm getting from Shopify in NetSuite and this happens because I'm unable to upload the attachment or file into the file cabinet.
Tried:
I tried to convert the file or attachment into base64 and also through blob too but unable to get the desired result because Netsuite has limitations that it can't handle more than 1000 characters and this also not a good workaround as the user has the privilege to update the image.
In Code:
Created an online HTML form and map their field with their related field and create a custom record for every record and I'm successfully able to map all the field except attachment(.png, .pdf, .png, etc)
Is there any way to get the result i.e successfully create the custom record through online HTML form or any other workaround to get the result?
For, Now whatever I checked or searched regarding upload image, maybe we are not able to upload an image into their respective field until and unless we save the particular file into the file cabinet.
So, I opt for some other method that is by going through suitelet and then POST the same form after storing the file in the file cabinet into the respective field.
Here, is my workaround code:
var dataBody = JSON.parse(request.getBody());
nlapiLogExecution("debug", "POST BLOCK", 'dataBody = ' + JSON.stringify(dataBody));
var file_folder = '2442342';
var contents = dataBody.imgdata;
var fileType = dataBody.fileType;
var date = new Date();
var newDate = date.getMilliseconds() + date.getTime();
var type = '';
var ext = '';
if ((fileType == 'plain') || (fileType == 'PLAIN')) {
type = 'PLAINTEXT';
ext = 'txt';
}
if ((fileType == 'pdf') || (fileType == 'PDF')) {
type = 'PDF';
ext = 'pdf';
}
if ((fileType == 'png') || (fileType == 'PNG')) {
type = 'PNGIMAGE';
ext = 'png';
}
if ((fileType == 'jpeg') || (fileType == 'JPEG')) {
type = 'JPGIMAGE';
ext = 'jpeg';
}
if ((fileType == 'jpg') || (fileType == 'JPG')) {
type = 'JPGIMAGE';
ext = 'jpg';
}
var name = newDate + '.' + ext;
nlapiLogExecution("debug", "POST BLOCK", 'File Type: ' + type);
try {
if (type) {
var uploadFile = nlapiCreateFile(name, type, contents);
uploadFile.setFolder(file_folder);
var FileId = nlapiSubmitFile(uploadFile);
nlapiLogExecution("debug", "POST BLOCK", 'Image File ID: ' + FileId);
}
if (FileId) {
warr.setFieldValue('custrecord_file_id', FileId);
}
} catch (err) {
nlapiLogExecution("debug", "POST BLOCK", 'Error: ' + err);
}
Hope it helps others. And one more thing you need to decrypt the data as you saving in the file cabinet but if you change the file type to jpg image in all then you may do not need to need to convert it.
Thanks
/**
* #NApiVersion 2.x
* #NScriptType Suitelet
* #NModuleScope SameAccount
*/
define(['N/ui/serverWidget', 'N/record', 'N/runtime', 'N/file', 'N/log'],
function(serverWidget, record, runtime, file, log) {
/**
* Definition of the Suitelet script trigger point.
*
* #param {Object} context
* #param {ServerRequest} context.request - Encapsulation of the incoming request
* #param {ServerResponse} context.response - Encapsulation of the Suitelet response
* #Since 2015.2
*/
function onRequest(context) {
if(context.request.method === 'GET'){
var formObj = serverWidget.createForm({
title: 'Attach Multiple Files'
});
var userId = runtime.getCurrentUser().id;
//User Name
var user = formObj.addField({
id: 'custpage_suitelet_user',
type: serverWidget.FieldType.SELECT,
source: 'employee',
value: userId,
label: 'USER'
});
user.defaultValue = userId;
//File fields
formObj.addField({
id: 'custpage_suitelet_file1',
type: serverWidget.FieldType.FILE,
label: 'File 1'
});
formObj.addField({
id: 'custpage_suitelet_file2',
type: serverWidget.FieldType.FILE,
label: 'File 2'
});
formObj.addField({
id: 'custpage_suitelet_file3',
type: serverWidget.FieldType.FILE,
label: 'File 3'
});
formObj.addSubmitButton({label: 'Submit'});
formObj.addResetButton({label: 'Reset'});
context.response.writePage(formObj);
}
else{
var userId = runtime.getCurrentUser().id;
var file1 = context.request.files['custpage_suitelet_file1'];
var file2 = context.request.files['custpage_suitelet_file2'];
var file3 = context.request.files['custpage_suitelet_file3'];
file1.folder = 624; //folder internal ID
file2.folder = 624; //folder internal ID
file3.folder = 624; //folder internal ID
var id1 = file1.save();
var id2 = file2.save();
var id3 = file3.save();
record.attach({
record: {
type: 'file',
id: id1
},
to: {
type: 'employee',
id: userId
}
});
record.attach({
record: {
type: 'file',
id: id2
},
to: {
type: 'employee',
id: userId
}
});
record.attach({
record: {
type: 'file',
id: id3
},
to: {
type: 'employee',
id: userId
}
});
var formObj = serverWidget.createForm({
title: 'File/s attached!'
});
context.response.writePage(formObj);
}
}
return {
onRequest: onRequest
};
});
I get the script from SuiteAnswers. It's for 2nd version of NS script. The suitelet can be used via an iframe. You could directly attach the file to a the record and/or populate the custrecord_file_id. This it not the best practice if you have limited storage space.
In my case, for return/repair form where the customer should upload a video or an image of the damaged product. I used the "google script" to upload the file into google drive and and I post only the URL to Netsuite via Suitelet.
As far as I can find, the file cabinet is not available to online forms.
As a workaround, you could have Shopify "receive" the file, then code it to send the file to NetSuite via a custom email capture plugin.
Put the right data on the subject line so your capture script knows where to put the file.

Using API tags for a library

I'm currently creating a library for an API. The endpoints have optional tags, and so I'm trying to create a way to use them in the functions.
import * as request from "request";
class Api {
key: string;
constructor(userInput: string) {
this.key = userInput;
}
champions(tags: object) {
Object.keys(tags).forEach(function(key) {
console.log(key + " = " + tags[key])
})
request(`https://api.champion.gg/v2/champions?api_key=${this.key}&${tags}`, function (error, response, body) {
if(!error && response.statusCode == 200) {
let info = JSON.parse(body)
}
});
}
}
var test = new Api("key")
test.champions({"champData": ["kda", "damage"], "rawr": ["xd", "lmao"]})
So far, the combining of Object.keys and forEach has allowed me to get the response of champData=kda,damage and rawr=xd,lmao, however, I need to be able to assign these to a variable that's usable in the URL. How can I get this to work?
Another issue that may occur later on is that, between each tag, there needs to be an & symbol, but not at the end. I apologize for throwing multiple problems into one, but because this is my first experience with something like this, I'm having many issues.
You can use Object.entries() and URLSearchParams()
const tags = {a:1, b:2, c:3};
const params = new URLSearchParams();
const key = "def";
Object.entries(tags).forEach(([key, prop]) => params.set(key, prop));
const url = `https://api.champion.gg/v2/champions?api_key=${key}&${params.toString()}`;
console.log(url);

JSON Store in worklight v6.0

I am trying to integrate the JSONStore standalone app in my multipage application. When I am trying to initialize the collection I am getting the following error "Uncaught TypeError: undefined is not a function". One thing I want to know is, in Worklight version 6.0 I observed that underscore (Lo-Dash) templating was used. But nowhere I found the reference given to the lodash. Also, I didn't find the lodash file anywhere. can anyone please tell me how to do this?
Here is my javascript code
window.$ = window.jQuery = WLJQ;
currentPage = {};
currentPage.init = function(WL, jQuery, lodash) {
alert("current page ::init called");
'use strict';
//Dependencies
var $ = jQuery,
_ = lodash;
//CONSTANTS
var PEOPLE_COLLECTION_NAME = 'people',
KEY_VALUE_COLLECTION_NAME = 'keyvalue',
INIT_FIRST_MSG = 'PERSISTENT_STORE_NOT_OPEN',
NAME_FIELD_EMPTY_MSG = 'Name field is empty',
AGE_FIELD_EMPTY_MSG = 'Age field is empty',
ID_FIELD_EMPTY_MSG = 'Id field is empty',
EMPTY_TABLE_MSG = 'No documents found',
DESTROY_MSG = 'Destroy finished succesfully',
INIT_MSG = 'Collection initialized',
ADD_MSG = 'Data added to the collection',
REPLACE_MSG = 'Document replaced succesfully, call find.',
REMOVE_MSG = 'Documents removed: ',
COUNT_MSG = 'Documents in the collection: ',
CLOSE_ALL_MSG = 'JSONStore closed',
REMOVE_COLLECTION_MSG = 'Removed all data in the collection',
LOAD_MSG = 'New documents loaded from adapter: ',
PUSH_MSG_FAILED = 'Could not push some docs, res: ',
PUSH_MSG = 'Push finished',
PASS_CHANGED_MSG = 'Password changed succesfully';
$('#init').click(initCollection);
$('#destroy').click(destroy);
$('#add-data').click(addData);
$('#find-name').click(findByName);
$('#find-age').click(findByAge);
$('#find-all').click(findAll);
$('#find-id-btn').click(findById);
$('#replace').click(replace);
$('#remove-id-btn').click(removeById);
//Log messages to the console and status field
var _logMessage = function (msg, id) {
//Get reference to the status field
var status = _.isUndefined(id) ? $('div#status-field') : $(id);
//Put message in the status div
status.text(msg);
//Log message to the console
WL.Logger.info(msg);
};
//Show JSONStore document in a table
var _showTable = function (arr) {
if (_.isArray(arr) && arr.length < 1) {
return _logMessage(EMPTY_TABLE_MSG);
}
//Log to the console
WL.Logger.ctx({stringify: true, pretty: true}).info(arr);
var
//Get reference to the status field
status = $('div#status-field'),
//Table HTML template
table = [
'<table id="user_table" >',
'<tr>',
'<td><b>_id</b></td>',
'<td><b>name</b></td>',
'<td><b>age</b></td>',
'<td><b>json</b></td>',
'</tr>',
'<% _.each(people, function(person) { %>',
'<tr>',
'<td> <%= person._id %> </td>',
'<td> <%= person.json.name %> </td>',
'<td><%= person.json.age %></td>',
'<td><%= JSON.stringify(person.json) %></td>',
'</tr>',
'<% }); %>',
'</table>'
].join(''),
//Populate the HTML template with content
html = _.template(table, {people : arr});
//Put the generated HTML table into the DOM
status.html(html);
};
//Scroll to the top every time a button is clicked
$('button').on('click', function () {
$('html, body').animate({scrollTop: 0}, 'slow');
});
function initCollection() {
console.log("init collection method called");
alert("init collection method called");
//Get references to the input fields DOM elements
var usernameField = $('input#init-username'),
passwordField = $('input#init-password');
//Get values from the input fields
var username = usernameField.val() || '',
password = passwordField.val() || '';
//Create the optional options object passed to init
var options = {};
//Check if a username was passed
if (username.length > 0) {
options.username = username;
}
//If if a password was passed
if (password.length > 0) {
options.password = password;
}
//JSONStore collections metadata
var collections = {};
//Define the 'people' collection and list the search fields
collections[PEOPLE_COLLECTION_NAME] = {
searchFields : {name: 'string', age: 'integer'},
//-- Start optional adapter metadata
adapter : {
name: 'people',
add: 'addPerson',
remove: 'removePerson',
replace: 'replacePerson',
load: {
procedure: 'getPeople',
params: [],
key: 'peopleList'
}
}
//-- End optional adapter metadata
};
//Define the 'keyvalue' collection and use additional search fields
collections[KEY_VALUE_COLLECTION_NAME] = {
searchFields : {},
additionalSearchFields : { key: 'string' }
};
//Initialize the people collection
WL.JSONStore.init(collections, options)
.then(function () {
_logMessage(INIT_MSG);
_callEnhanceToAddKeyValueMethods();
})
.fail(function (errorObject) {
_logMessage(errorObject.msg);
});
}
Thanks in advance
regards
V.H.C
I observed that underscore(loadash) templating was used. But nowhere I
found the reference given to the loadash. Also, I didn't find the
loadash file anywhere. can anyone please tell me how to do this?
You can build your own version of lodash or use underscore.
The version of lodash used by worklight is in the WL_ variable. Looking at your code, maybe you want to replace _ = lodash with _ = WL_. Alternatively when you bring your own version lodash or underscore it will be assigned to the _ variable automatically.
Alternatively, you can use other string template libraries like Handlebars.js or basic string interpolation by modifying the String prototype.

Win 8 Apps : saving and retrieving data in roamingfolder

I'm trying to store few user data into a roamingFolder method/property of Windows Storage in an app using JavaScript. I'm following a sample code from the Dev Center, but no success. My code snippet is as follows : (OR SkyDrive link for the full project : https://skydrive.live.com/redir?resid=F4CAEFCD620982EB!105&authkey=!AE-ziM-BLJuYj7A )
filesReadCounter: function() {
roamingFolder.getFileAsync(filename)
.then(function (filename) {
return Windows.Storage.FileIO.readTextAsync(filename);
}).done(function (data) {
var dataToRead = JSON.parse(data);
var dataNumber = dataToRead.count;
var message = "Your Saved Conversions";
//for (var i = 0; i < dataNumber; i++) {
message += dataToRead.result;
document.getElementById("savedOutput1").innerText = message;
//}
//counter = parseInt(text);
//document.getElementById("savedOutput2").innerText = dataToRead.counter;
}, function () {
// getFileAsync or readTextAsync failed.
//document.getElementById("savedOutput2").innerText = "Counter: <not found>";
});
},
filesDisplayOutput: function () {
this.filesReadCounter();
}
I'm calling filesDisplayOutput function inside ready method of navigator template's item.js file, to retrieve last session's data. But it always shows blank. I want to save upto 5 data a user may need to save.
I had some trouble running your code as is, but that's tangential to the question. Bottom line, you're not actually reading the file. Note this code, there's no then or done to execute when the promise is fulfilled.
return Windows.Storage.FileIO.readTextAsync(filename);
I hacked this in your example solution and it's working... typical caveats of this is not production code :)
filesReadCounter: function () {
roamingFolder.getFileAsync(filename).then(
function (filename) {
Windows.Storage.FileIO.readTextAsync(filename).done(
function (data) {
var dataToRead = JSON.parse(data);
var dataNumber = dataToRead.count;
var message = "Your Saved Conversions";
//for (var i = 0; i < dataNumber; i++) {
message += dataToRead.result;
document.getElementById("savedOutput1").innerText = message;
//}
//counter = parseInt(text);
//document.getElementById("savedOutput2").innerText = dataToRead.counter;
}, function () {
// readTextAsync failed.
//document.getElementById("savedOutput2").innerText = "Counter: <not found>";
});
},
function () {
// getFileAsync failed
})
},