How to re-run the test with different data using TestNG - selenium-webdriver

Currently we are re-running the test when a Test Fails using TestNG iRetryAnalyzer.
Problem that we are facing is:
We have a Test to 'Add a user'. For the first time after adding a user, in the process of checking the success message exception occurred (Timeout/NosuchElement) etc But the user is added in the database.
Now again when we re-run the test with same data, the Test Fails as user is already Added.
How can i overcome this??
As here the Data, the user email id unique field. Atleast I should be able to change the Email Id when im re-running it for the second time.
Please help me.

If you just need to create a unique, fake email address that you don't need to actually use, you can always append a date/time stamp to some base email you get from your DataProvider:
#Test(dataProvider = "dp")
public void emailTest(String userName, String emailShortname) {
//Get the current time
long time = System.currentTimeMillis();
//append it to the email from your DataProvider
StringBuilder emailBuilder= new StringBuilder();
emailBuilder.append(emailShortname).append("_").append(time).append("#gmail.com");
//do user creation code below using emailBuilder result...
I would say that if you are going to do these sorts of tests using Selenium, you're going to fill up your database with junk test IDs, so I'd suggest your team create a mechanism to clean these out either as part of the test run or after it.

Ideally, if there is a way to delete a user. You should use that in the #aftertest method and remove that user.
This way the next time you will be again able to use the same email id irrespective of the test is successful or not.
If not and if the email id is never verified ( I mean like some confirmation email which you use to confirm the user) you can create fake email id on the fly like xyz123#gmail.com. If the email id is verified then i guess you are in trouble.

Related

Sending emails to multiple users using flows(Salesforce)

I need to send an email notification to the record owner and manager once the opportunity is closed-won.
adding only owner email works fine
adding only manager email works fine
But if I add both together with coma, {!$Record.Owner.Email},{!$Record.Engagement_Manager__r.Email} I'm getting error.
what is the correct way to add it?
You can try creating a Formula Resource in your flow like this but, in your case, using $Record.Owner.Email and $Record.Engagement_Manager__r.Email:
Then, you can use this Resource in your Email Action:
Try the below code and let me know if it works.
global class SendPurchaseOrderEmail {
WebService static void sendEmail(String poId) {
List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();
String theTemplate = [SELECT Id FROM EmailTemplate WHERE DeveloperName = 'Purchase_Order_With_Items'].Id;
User theUser = [SELECT Id FROM User WHERE Name = 'user name goes here'];
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setSaveAsActivity(false);
mail.setTemplateId(theTemplate);
mail.setWhatId(poId);
mail.setTargetObjectId(theUser.Id);
mail.setToAddresses(new String[] { 'TestUser#salesforce.com' ,'abc#test.com'}); //add other emails here.
emails.add(mail);
Messaging.sendEmail(emails);
}
}
Please refer below link for more details.
https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_calls_sendemail.htm
This is because you have to pass a direct email address there.
Instead of that, you can create a collection variable, store the emails into it, then pass that variable to email addresses (collection) field.
Note: you can only store upto 5 emails into that colllection variable at a time.
Hi For that you can simply add collection Variable.
For that variable assign multiple values to it. So that you can send email to both record owner as well as manager.
From New Resource Select the Variable and click Allow Multiple Values and Data-type as text.
Then by using Assignment. Add the following email Address to it Please refer the below image.
I hope you have got the solution
Thanks

Laravel 8 Fortify User UUID Login Problem

I am currently setting up a new project using Laravel 8. Out of the box, Laravel is configured to use auto-incrementing ID's for the user's ID. In the past I have overrode this by doing the following.
Updating the ID column in the user table creation migration to
$table->uuid('id');
$table->primary('id');
Adding the following trait
trait UsesUUID
{
protected static function bootUsesUUID()
{
static::creating(function ($model) {
$model->{$model->getKeyName()} = (string) Str::orderedUuid();
});
}
}
Adding the following to the user model file
use UsesUUID;
public $incrementing = false;
protected $primaryKey = 'id';
protected $keyType = 'uuid';
On this new project, I did the same as above. This seems to break the login functionality. When the email and password are entered and submitted, the form clears as though the page has been refreshed. Thing to note is there are no typical validation error messages returned as would be expected if the email and/or password is wrong.
To check that the right account is actually being found and the password is being checked properly, I added the following code to the FortifyServiceProvider boot method. The log file confirms that the user is found and the user object dump is correct too.
Fortify::authenticateUsing(function(Request $request) {
\Log::debug('running login flow...');
$user = User::where('email', $request->email)->first();
if ($user && Hash::check($request->password, $user->password)) {
\Log::debug('user found');
\Log::debug($user);
return $user;
}
\Log::debug('user not found');
return false;
});
Undoing the above changes to the user model fixes the login problem. However, it introduces a new problem that is the login will be successful but it wont be the right account that is logged in. For example, there are 3 accounts, I enter the credentials for the second or third account, but no matter what, the system will always login using the first account.
Anyone have any suggestions or ideas as to what I may be doing wrong, or if anyone has come across the same/similar issue and how you went about resolving it?
Thanks.
After digging around some more, I have found the solution.
Laravel 8 now stores sessions inside the sessions table in the database. The sessions table has got a user_id column that is a foreign key to the id column in the users table.
Looking at the migration file for the sessions table, I found that I had forgot to change the following the problem.
From
$table->foreignId('user_id')->nullable()->index();
To
$table->foreignUuid('user_id')->nullable()->index();
This is because Laravel 8 by default uses auto incrementing ID for user ID. Since I had modified the ID column to the users table to UUID, I had forgotten to update the reference in the sessions table too.

Keeping same session, 1 single browser

The title of the question may be irrelevant to what I am trying to find out. My goal is to write a test that will
A) login to Hotmail
B) Delete the junk mail in my junk folder.
Design wise I have created 2 separate test classes. TestSignInPage1.class is only testing the user login part which is working and passed.
TestJunkFolderDelete.class will go to junk mail folder and do the deletion. I understand I simply can’t use the junk delete test on its own, a user 1st needs to login to the account so I called the TestSignInPage1 class in the junk folder.
#Test
public void testJunk(){
//The part below will get my login credential from TestSignPage class
TestSignInPage1 t= new TestSignInPage1();
t.testPage1();
//The following part will handle junk folder clean operation
WebDriver driver=br.openBrowser("firefox", "https://outlook.live.com/owa/?realm=hotmail.com&path=/mail/junkemail");
JunkMail jm= PageFactory.initElements(driver, JunkMail.class);
jm.doJunkClean();
Problem: Once the login part has been executed, the junk folder delete test opens up another new browser and again asks for login information.
Question: In professional world how would you tackle this (i.e.: you will have 1 test only, is there a way to keep the same session 1 browser) etc?

Updating user info in liferay database

I need to update info of an existing user in my database programmaticaly
I need to update user name birth date values in user_ table in Liferay database
basically I need to run an update query.
It is not recommended to update the liferay database directly, you should use Liferay API instead to do these things. As per this liferay forum post:
The Liferay database is not published for a reason. The reason is the API does significantly more stuff than just simple SQL insert statements. There are internally managed foreign keys, there are things which are updated not just in the database but also in the indices, in jackrabbit, etc.
Since all of this is managed by the code and not by the database, any updates to the code will change how and when the database is updated. Even if it did work for you in a 6.1 GA1 version, GA2 is coming out in a couple of weeks and the database/code may change again.
Sticking with the API is the only way to insure the changes are done correctly.
Ok enough preaching and back to your problem, here are some ways you can do these:
you can either build a custom portlet and use liferay's services and update the username, birthdate etc using UserLocalServiceUtil.updateUser() method.
Or you can build a web-service client based on SOAP or JSON to update the details which would call the same method
Or you can use Liferay's Beanshell tool to do this from the control panel, following is some code to update the user (created just for you ASAP):
import com.liferay.portal.model.Company;
import com.liferay.portal.model.Contact;
import com.liferay.portal.model.ContactConstants;
import com.liferay.portal.model.User;
import com.liferay.portal.service.CompanyLocalServiceUtil;
import com.liferay.portal.service.ContactLocalServiceUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
long companyId = 10135; // this would be different for you
User user = UserLocalServiceUtil.getUserByEmailAddress(companyId, "test#liferay.com");
// Updating User's details
user.setEmailAddress("myTest#liferay.com");
user.setFirstName("First Test");
user.setLastName("Last Test");
user.setScreenName("myTestScreenName");
UserLocalServiceUtil.updateUser(user, false);
// Updating User's Birthday
// December 12, 1912
int birthdayMonth = 11;
int birthdayDay = 12;
int birthdayYear = 1912;
Calendar cal = new GregorianCalendar();
cal.set(birthdayYear, birthdayMonth, birthdayDay, 0, 0, 0);
cal.set(Calendar.MILLISECOND, 0);
Date birthday = cal.getTime();
System.out.println("Updated User: " + user + "\nBirthdate to be updated: " + birthday);
long contactId = user.getContactId();
Contact contact = ContactLocalServiceUtil.getContact(contactId);
if(contact == null) {
contact = ContactLocalServiceUtil.createContact(contactId);
Company company = CompanyLocalServiceUtil.getCompany(user.getCompanyId());
contact.setCompanyId(user.getCompanyId());
contact.setUserName(StringPool.BLANK);
contact.setCreateDate(new Date());
contact.setAccountId(company.getAccountId());
contact.setParentContactId(ContactConstants.DEFAULT_PARENT_CONTACT_ID);
}
contact.setModifiedDate(new Date());
contact.setBirthday(birthday);
ContactLocalServiceUtil.updateContact(contact, false);
System.out.println("Users birthdate updated successfully");
The contact code is built with the help of Liferay's source code for UserLocalServiceImpl#updateUser method
In case you are wondering what is bean-shell and where to put this code, here is where you can find it in Liferay Control Panel Control Panel --> Server --> Server Administration --> Script
It depends on whether you have to do this in a portlet code or by sending a direct query to db.
Liferay basically caches everything, so if you update a record in the Liferay database while the portal is running, most likely that record is already in cache, and so the new column values won't be read at all. You will have to clear the database cache by going to Control Panel -> Server Administration.
On the contrary, if you have to do such a thing in a portlet code, you should call one of the methods of the Liferay services. You're trying to update a User, so you should call the method UserLocalServiceUtil.updateUser (or UserServiceUtil.updateUser if you also want to check permissions).
You can see there are some different updateUser methods, one of them has a lot of parameters and another has only the bean as a parameter. While the first one contains all the business logic (validation, reindexing, update of related entities, etc.), the second one was just autogenerated and should not be used (except when you absolutely know what you're doing). So, use the method with a lot of parameters, simply passing user.getCOLUMN() (eg. user.getFacebookId()) if you don't want to change the value of that column.
Hope it helps, and sorry for my bad English...
update user_ set firstName="New First Name", lastName="New Last Name" where emailAddress="test#test.com";
update contact_ set birthday="date string" where contactId in(select contactId from user_ where emailAddress="test#test.com");
By first update query you can change firstName, lastName of user and by second query you can change birthdate of user.
Hope its clear!
Try this code..
Here i am updating only user First name(rest you can do by your own way)
userId = you can get this using theme display
User user = UserLocalServiceUtil.getUser(userId);
user.setFirstName("new name");
UserLocalServiceUtil.updateUser(user);
Hope this will help you !!!

Salesforce- Creating contact and user by importing CSV file & send notification email to User

I want to create the contact & user related to account by importing csv file.After creating user, generated username & password should be send to the respective user's email address.
I am planning to use Vf page for accepting the csv file & the Contact & User API for adding contacts & Users. But I am not sure regarding the email notification to user through API.
So can anyone please provide me the best solution for this?
You'll need to use Database.insert() flavor instead of straightforward insert users;
Check out the DML options help topic, especially the "emailHeader" property
Something like this should do the trick:
List<User> users = new List<User>(); // fill in with data from your CSV
Database.DMLOptions dlo = new Database.DMLOptions();
dlo.EmailHeader.triggerUserEmail = true;
database.insert(users, dlo);
Be aware though that you can't insert an inactive user. You can deactivate them straight after the insert but then they can't login so you'll probably want to suppress the sending of email, not enforce it. Make sure you have sufficient amount of licenses before you start!
Last but not least - you can cheat by setting the same password for them with System.setPassword('user id', 'new password') :) It's not recommended to expose this functionality to your end users though, can process only 1 user at a time and wastes 1 DML statement...

Resources