I have a form inside my page for user that want to register inside the site. After registration I insert user inside database create an activation key and send an email, until user doesn't click the link inside the email with the activation key he can't login inside the site.
With CasperJS I would like to test this functionality, the fillForm is ok but how can I test the activation key?
I have thought to create an input hidden with the activation key (only if is in TEST mode not i production!) and retrieve this value with getFieldValue function.
Is this the right way to do it or there is a better mode to do?
this is my casperjs test to retrieve activation key after registration (I create an input hidden with the activation code):
view = 'users/registered';
casper
.start(webroot + view)
.then(function() {
__utils__.log("Retrieving data from input activation-key");
activationKey = __utils__.getFieldValue('activation-key');
}).then(function() {
__utils__.log("Activating account with the key " + activationKey);
}).then(function(){
this.evaluate(function() {
__utils__.log("Activating account with the key " + activationKey);
window.location = webroot + 'users/activate/' + activationKey;
});
}).then(function(){
this.echo(this.getCurrentUrl());
});
casper.run(function() {
this.echo('test registeration successful!').exit();
});
casper.viewport(page.width, page.height);
casper.test.done();
I managed to do what i wanted with registration, it could help you : CasperJS- Register on a site and validate the mail sent on Gmail -for both slimer and phantom-
And before i did some scraping with an activation code too, for manual activation (pure JS, no jQuery here, i didn't want to inject JQuery on gmail DOM environment) :
this.waitForSelector("div.msg",function(){
this.test.assertSelectorHasText("a","Activation message");
//var code declared in the main scope
code = this.evaluate(function(){
var strongs = document.getElementsByTagName('strong')
,i
,l = strongs.length
;
for (i = 0; i < l; ++i) {
if(strongs[i].textContent === "activation code:"){
//get back the code in DOM context -> split to get back only what I want
return (strongs[i].parentNode.textContent.split(' ')[2]);
}
}
});
this.echo("code : " + code,"INFO");
});
Related
I have a set of scripts that I'm using that interact with each other. I use a client, user event and suitelet script to create a button that, when pressed, opens a popup with a list of items filtered by vendor.
It works fine when I'm in edit however when I use it while creating a record problems arise. Since the record to be created has no vendor or id I can't retrieve an item by vendor. What I'm trying to do is to have the Suitelet retrieve the info from the vendor field that is entered prior to it being saved. Therefore I can filter all the items by vendor and add the necessary items in one go. Is this possible? Am I able to access the info before it is submitted.
Below are the Client and Suitelet. The User Event is just a call to the suitelet so for the sake of brevity I left it out.
Client Script
function addItemButtonCallback(data){
nlapiSelectNewLineItem('item');
nlapiSetCurrentLineItemValue('item', 'item', data);
nlapiCommitLineItem('inventoryitem');
}
function addItemButton() {
var id = nlapiGetFieldValue('id');
if (id != "") {
var url = nlapiResolveURL('SUITELET', 'customscript_val', 'customdeploy1') + '&poId='+id;
window.open(url, '_blank', 'width=500,height=500');
}
}
Suitelet
function suitelet(request, response){
if(request.getMethod() == 'GET') {
var form = nlapiCreateForm('Add Item');
form.addSubmitButton('Submit');
var itemfield = form.addField('custpage_val', 'select', 'Item');
var id = request.getParameter('id');
var rec = nlapiLoadRecord('purchaseorder', id);
var vend = rec.getFieldValue('entity');
var search = nlapiSearchRecord(...search parameters...);
for (result in search){
if (search[result].getValue('vendor') == vend){
itemfield.addSelectOption(search[result].id, nlapiLookupField('inventoryitem', search[result].id, 'itemid'));
}
}
response.writePage(form);
} else {
var data = request.getParameter('custpage_item');
response.write('<html><body><script>window.opener.addItemButtonCallback("'+data+'"); window.close();</script></body></html>');
}
}
Use nlapiGetFieldValue('entity') on the clientscript and pass it to the Suitelet using a query parameter just like you are doing with poId (if you do this you might not even need poId after all + no need to load the record on the suitelet).
Also, you might want to optimize your code by running one search passing an array of itemids instead of calling nlapiLookupField for each item.
You might need to modify your beforeLoad so the entity is inserted dynamically when the button is pressed (I cant remember if clientscript button does this) . Something like this:
var suiteletURL = nlapiResolveURL('SUITELET', 'customscript_val', 'customdeploy1');
var script = "var entity = nlapiGetFieldValue('entity'); var url = '" + suiteletURL + "'&entityId=' + entity;window.open(url, '_blank', 'width=500,height=500')";
var button = form.addButton('custpage_addItemButton', 'Add Item', script);
I use ContentTools for my content editor/PHP CMS.
I'm trying to pass additional values from a "editable div" to the POST array (then it will be stored in a database).
The script uses Javascript to get the data and to make the call to my server side code.
Relevant JS code for the saving process:
// Collect the contents of each editable region into a FormData instance
payload = new FormData();
//payload.append('__page__', window.location.pathname);
payload.append('page_id', page_id); // Page ID from the Meta Property
for (name in regions) {
payload.append(name, regions[name]);
//payload.append('template', 'template');
}
// Send the updated content to the server to be saved
onStateChange = function(ev) {
// Check if the request is finished
if (ev.target.readyState == 4) {
editor.busy(false);
if (ev.target.status == '200') {
// Save was successful, notify the user with a flash
if (!passive) {
new ContentTools.FlashUI('ok');
}
} else {
// Save failed, notify the user with a flash
new ContentTools.FlashUI('no');
}
}
};
xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', onStateChange);
xhr.open('POST', 'update-page.php'); // Server side php file, which will catch the $_POST array.
xhr.send(payload);
Below you see an example editable div which will be in the POST array when page is saved after editing.
Note that the div has additional custom html tags 'data-template'.
<div id="content_4" class="content" data-template="5" data-editable data-name="1">
This is some example website text.
This is some other example website text.
</div>
I'm trying to pass along the values from "data-template".
What I've tried so far does not work:
// Added in: editor.addEventListener('saved', function (ev) {
var template = document.querySelector("div[data-template]"); // Get Template name from editable div
// Or
var template = document.getElementsByTagName("[data-template]")[0].getAttribute('[data-template]');
// Added in: the For In Loop
for (name in regions) {
payload.append(name, regions[name]);
payload.append('template', template); // added but does not work
}
Also, I don't want to use the div ID as value to be passed on.
I'm still trying other ways, but my JavaScript knowledge is not (yet!) as strong as my PHP knowledge.
Does someone know a solution to this issue?
There must be simple solution to get the value from the data-template, passed on to the POST (only the data-template value of the changed content in the div).
Right?
You can select the template data for each region by selecting the region's DOM element by it's editable name (e.g data-name):
for (var name in regions) {
// Select the region DOM element
var regionDOM = document.querySelector('[data-name="' + name + '"]');
// Get the `data-template` attribute
var tpl = regionDOM.getAttribute('data-template');
// Add the region HTML and template to the payload
payload.append(name, regions[name]);
payload.append('template_' + name, tpl);
}
The reason you get no value for for template at all in your code is that you're calling the getAttribute method with the CSS selector and not just the attribute name you want, e.g .getAttribute('[data-template]') should be .getAttribute('data-template').
The other difference in the code I've posted is that the template for each region is saved. If it will be the same template for all regions then you could modify the code to be:
for (var name in regions) {
// Select the region DOM element
var regionDOM = document.querySelector('[data-name="' + name + '"]');
// Get the `data-template` attribute
var tpl = regionDOM.getAttribute('data-template');
// Add the region HTML and template to the payload
payload.append(name, regions[name]);
}
// Set the template value for the payload to that of the last region
// found.
payload.append('template', tpl);
I have a custom object in Salesforce called Website_Role__c. This object has a list of people associated with a store with different roles (Owner, Mentor, etc.).
Using JavaScript in a Salesforce button on Account:
The desired behavior is a user clicks the button and a dialog pops up with the list of people in the Website_Role__c for that Account. There would be a checkbox next to each person allowing the user to select them.
We are using eSign (formerly EchoSign). This button is a "Send with eSign" button that will be used to send an agreement to the list of people from Website_Role__c.
This is where I am at now:
/*My Attempt*/
{
!REQUIRESCRIPT("/soap/ajax/19.0/connection.js")
} //adds the proper code for inclusion of AJAX toolkit
var url = parent.location.href; //string for the URL of the current page
var records = {!GETRECORDIDS($ObjectType.Website_Role__c)
}; //grabs the Website Role records for the currently selected store
var updateRecords = []; //array for holding records that this code will ultimately update
if (records[0] == null) { //if the button was clicked but there was no record selected
alert("Please select at least one person to send to."); //alert the user that they didn't make a selection
} else { //otherwise, there was a person selected
for (var a = 0; a < records.length; a++) { //for all records
var update_Website_Role__c = new sforce.SObject("Website_Role__c"); //create a new sObject for storing updated record details
//This is where I get lost. Not sure if this is even the correct approach
}
//??
parent.location.href = url; //refresh the page
}
I would greatly appreciate any help you can provide.
Thank you
Try something like this:
{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")}
var query = sforce.connection.query("SELECT Owner__c, Mentor__c FROM Website_Role__c WHERE Account__c ='{!Account.Id}'");
var records = query.getArray("records");
alert("Owner is: " + records[0].Owner__c);
This assumes you have a reference field on your Website_Role object that points to the Account.
Check here for some more examples
https://developer.salesforce.com/docs/atlas.en-us.ajax.meta/ajax/sforce_api_ajax_more_samples.htm
I created a button in Salesforce using JavaScript which converts an enquiry (custom object) to a registration (Contact). The button works for myself and any test user I log in as on the same profiles and permissions, however one of my users is report an error when they use the button.
The error is as follows:
'unterminated string constant'
The Code I'm using in the button is as follows:
{!REQUIRESCRIPT('/soap/ajax/27.0/connection.js')}
alert('Migration in progress, this page will refresh once it is complete. Please click ok, Please DO NOT press this button again');
if ('{!Enquiry__c.Surname__c}' != ''){
if ('{!Enquiry__c.Client_if_already_on_the_system__c}' == ''){
var Reg = new sforce.SObject('Contact');
Reg.FirstName = '{!Enquiry__c.First_Name__c}';
Reg.LastName = '{!Enquiry__c.Surname__c}';
Reg.Gender__c = '{!Enquiry__c.Gender__c}';
Reg.MailingStreet = '{!Enquiry__c.Address__c}';
Reg.MailingPostalCode = '{!Enquiry__c.Post_Code__c}';
Reg.MailingCity = '{!Enquiry__c.City_Town__c}';
Reg.MailingState = '{!Enquiry__c.County__c}';
Reg.HomePhone = '{!Enquiry__c.Home_Number__c}';
Reg.MobilePhone = '{!Enquiry__c.Mobile_Number__c}';
Reg.Email = '{!Enquiry__c.E_mail__c}';
Reg.Lastest_Enquiry__c = '{!Enquiry__c.Id}';
result = sforce.connection.create([Reg]);
if (result[0].success == 'true'){
alert('A new Registration with the name - ' + Reg.FirstName + ' ' + Reg.LastName + ' was successfully created, Please DO NOT press this button again as duplication\'s will be created, Your client will be automatically connected to this enquiry');
javascript: document.location.reload(true);
}
}else{
alert('Cannot Migrate to Registration as there is already a Client connected to this Enquiry');
}
}else{
alert('Cannot Migrate to Registration as Surname is blank!');
}
The user has told me they are using IE as a browser, I've tested the button on Chrome, Edge and the most up to date IE. Anyone have any ideas of whats wrong?
what is the type for Reg.FirstName and LastName? Are you using textarea type for these two fields?
Because if user enter any of the name with a carriage return \r or \n alert will fail with the same error and it will be a random based on the input.
I have a problem with the messaging channel in HTML 5
On one side I have the code:
<iframe id="ifr" src="receive.html" onLoad="initMessaging()" ></iframe>
<button onClick="postMsg()">Wyslij</button>
<script type="text/javascript">
var channel = new MessageChannel();
channel.port1.onmessage = function (evt) {
alert(evt.origin + ": " + evt.data);
};
function initMessaging() {
var child = document.getElementById("ifr");
child.contentWindow.postMessage('hello', 'http://localhost:85', [channel.port2]);
}
function postMsg() {
channel.port1.postMessage('Message sent from ' + location.host);
}
And on second site:
<input type="button" value="Post Message" onClick="postMsg();" />
<script type="text/javascript">
var port = null;
window.addEventListener("message", function (e) {
port = e.ports[0];
port.onmessage = function (e){
port.addEventListener("message", function (evt) {alert("Received message \"" + evt.data + "\" from domain: " + evt.origin);
}, false);
}
}, false);
function postMsg() {
if(port) {
port.postMessage("Data sent from " + location.host);
}
Why Its doesnt working? What I do wrong?
Thx a lot for help!
I think you need to use a form to call the postMessage function and send the message. Here's a tutorial that shows a simpler way of getting this done.
HTML5 postMessage interface is not good. I propose an intuitive one. you can download it from my site:
http://www.jackiszhp.info/tech/postMSG.html
window.MSG.post(msgname, msgdata, arrayOfDomainTarget, arrayOfWindowIDTarget)
this 'window' can be omit, not similar to the one specified in HTML5
there you need an window object.
Here, you do not. this 'window' just indicate MSG is in the global space.
msgname is the the name the message category.
msgdata is a JSON object. it will be stringified before post
arrayOfDomainTarget, arrayOfWindowIDTarget
I use logical AND. originally it was OR
later I changed it to AND. more appropriate. I guess.
and I let "*" to be the wildcard for all windowID.
the caller's information does not present in the parameter at all
since the browser knows all the information.
so we can see that this method does not allow the sender to fool the receiver.
the sender just call as follows.
window.name="myWindowID";
MSG.post("cmd",{what:'do thing abc',parameter:'the value of a parameter'},["jackiszhp.info"],[*]);
for the receiver, 2 things.
//#1 define the message handler
function messageHandler(e){
var obj=JSON.parse(e.detail);
obj.name is the msgname = 'cmd'
obj.data is the msgdata = {what:'fuck',who:'not to tell'};
obj.source is the sender
obj.source.href is the sender's window.location.href
obj.source.WID is the sender's window.name="myWindowID";
obj.target is the target of this event
obj.target.domains is the target domains of this event
obj.target.WIDs is the target WIDs of this event
....
}
//#2 register the message handler
window.addEventListener(msgname, messageHandler,false);
or
document.addEventListener(msgname, messageHandler,false);
//to respond,
window.name="hereMywindowID";
MSG.post("cmd",{what:'do thing def',parameter:'the value of a parameter'},["jackiszhp.info"],['myWindowID']);
//clearly, we can see that this response only the original sender can receive it.
//unless in the target domain, accidently, there are two windows with same ID "myWindowID".
Additional note:
A. window can be uniquely identified. but here, I did not use it. I use window.name instead. about window ID, you can check this link: https://developer.mozilla.org/en-US/docs/Code_snippets/Windows#Uniquely_identifying_DOM_windows
B. I hope the mozilla can take my interface and include it into the firefox.