selenium cucumber javascript use faker to fill different value on iteration - javascript

I am new on automation selenium using javascript, I have simple code like below that I am using faker data to generate random email, question is incase I have data table on scenario outline 2 types, when I run the code some how the data for email for second loop is using same data that generated on first loop, question is how to get different data for 2nd loop?
#feature file
#RegisterMerchant
Feature: Register new merchant
Scenario Outline: As a new User, I want to create new merchant account
Given User is on register page
When User fill register form for "<businessChannel>" merchant
And User click register
Then User should see success pop up message
Examples:
| businessChannel |
| offline |
| online |
#data file
const faker = require('faker')
class registerData {
email = faker.name.firstName().toLowerCase() + faker.name.lastName().toLowerCase() + "#mailinator.com"
}
module.exports = new registerData()
#step file
const { Given, When, Then } = require('cucumber');
const registerPage = require('../PageObjects/registerMerchantPage')
Given(/^User is on register page$/, () => {
registerPage.isOnRegisterPage()
});
When(/^User fill register form for "([^"]*)" merchant$/, (businessChannel) => {
registerPage.inputRegisterForm(businessChannel) ..
});
When(/^User click register$/, () => {
registerPage.signUpButton.click()
});
Then(/^User should see success pop up message$/, () => {
registerPage.showPopUpSuccess()
});
Actual the 2nd iteration still using 1st faker data
#page object file
inputRegisterForm(businessChannel) {
this.emailAddressField.addValue(registerData.email)
switch (businessChannel) {
case "online":
this.onlineRadBtn.click()
break;
case "offline":
this.offlineRadBtn.click()
break;
}
}

solved by add function for this data file :
email = faker.name.firstName().toLowerCase() + faker.name.lastName().toLowerCase() + "#mailinator.com"
to be like this
#data file
class registerData {
generateRegisterData() {
this.email = faker.name.firstName().toLowerCase() + faker.name.lastName().toLowerCase() + "#mailinator.com"
console.log("Test")
}
email = ""
#page object file
inputRegisterForm(businessChannel) {
registerData.generateRegisterData()
this.emailAddressField.addValue(registerData.email)
switch (businessChannel) {
case "online":
this.onlineRadBtn.click()
break;
case "offline":
this.offlineRadBtn.click()
break;
}
}

Related

Remove session params if dropdown value changed

Is it possible to delete session[:sth] using jQuery/Javascript ?
In the Rails controller I set the session parameters:
def new
#other logic (...)
session[:patient_id_to_add_caregiver] = params[:patient_to_caregiver]
end
Below I've got simple function to handle case when the user selects one field from dropdown list, search field and search results should be hidden:
registrants.js
function toggle_caregiver_fields_on_ready(){
var caregiverSectionElement = $("#registrant_registration_attributes_registrant_id");
if ($("#registrant_registration_attributes_registered_as").val() === 'caregiver') {
$('.patient-caregiver-section').removeClass('hidden');
$('#patient-search-results').removeClass('hidden');
} else {
$('.patient-caregiver-section').addClass('hidden');
$('#patient-search-results').addClass('hidden');
}
}
In the same JS function I want to clear session[:patient_id_to_add_caregiver] when (#registrant_registration_attributes_registered_as").val() === 'caregiver'). I've tried with sessionStorage.clear(); to be:
if ($("#registrant_registration_attributes_registered_as").val() === 'caregiver') {
sessionStorage.clear();
$('.patient-caregiver-section').removeClass('hidden');
(...)
But nothing happened. Is it possible to clear this session storage?

Pass variable with subvariable from JQuery to Flask app

I have a Flask that uses WTForms and Jquery to take from the user "input" fields in a form and shows "select" fields to the user. Jquery is used to filter the select fields shown to the user based on what they enter in the input fields. In order to filter the select fields, I need to take what the user enters in the input fields and send it to the Flask app.
These are the form fields -
class TableName(FlaskForm):
schema = StringField('Schema', validators=[DataRequired()], id = 'schema_name')
table = StringField('Table', validators=[DataRequired()], id = 'table_name')
class QaForm(FlaskForm):
test_table_in = FormField(TableName, id = 'test_table')
prod_table_in = FormField(TableName, id = 'prod_table')
This is the JQuery -
$(function() {
var tables = {
test_table: $('test_table_in-schema_name').val() + "." + $('test_table_in-table_name').val(),
prod_table: $('prod_table_in-schema_name').val() + "." + $('prod_table_in-table_name').val()
};
var fields = {
test: [$('#select_test_join_key'), $('#select_test_dimensions')],
prod: [$('#select_prod_join_key'), $('#select_prod_dimensions')]
};
fields.test.forEach(item => updateFields(tables.test_table, item));
fields.prod.forEach(item => updateFields(tables.prod_table, item));
function updateFields(table, field) {
var send = {
table: tables.table
};
$.getJSON("{{url_for('_get_fields') }}", send, function(data) {
//do something
});
}
});
When the user enters a "test_table", the test table should get passed to _get_fields() and when the user enters a prod_table, that value should get sent to _get_fields(). Test_table and prod_table are two form fields, each consisting of two subfields, "schema" and "table" that are combined to create one field in the format "schema.table".
Function _get_fields() in Flask view to receive the table name -
#app.route('/_get_fields/')
def _get_fields():
table = request.args.get('table', type=str)
fields_query = f"""select column_name AS Fields from information_schema.columns WHERE
table_name = '{table}' group by 1 limit 10;"""
conn.execute(fields_query)
result = conn.fetchall()
return jsonify(result)
Potential errors:
It's the request_args.get() function in the Flask view that I believe is not referring correctly to the JQuery variables. I've tried 'test_table', 'prod_table', and others but none of these have worked so far. I'm using the "name" of the input form elements to create the table variables - I'm wondering if that may be a part of the issue as well. Any thoughts or suggestions?

How to store data from api call with vanilla javascript to firestore database?

I am bringing in data from an api call and outputting the data to html inside a template string using variables from the main.js file. All of that works fine. The problem that has me blocked is I want to have an add to favorites button that a user can click and add the title to a favorites list. When I add the button inside the template literal the addEvenListener I have for the button is null and if I add the button to the index.html I cannot access the data from the api. I am trying to store the data first into firestore database after the user clicks the button. Then output the data into a dropdown list.
I've added a collection to the firestore database and can display the data from the backend to the favorites list but I need to grab the data from the front end, store it on the back end, and display it in the favorites list.
function getMovie(){
let movieId = sessionStorage.getItem('movieId');
// Make a request for a user with a given ID
axios.get("https://api.themoviedb.org/3/movie/" + movieId + "?
api_key=redacted")
.then(function (response) {
console.log(response)
let movie = response.data;
//console.log(movie);
let output = `
<div class="dropdown">
<button class="dropbtn" id="dropbtn">Favorites</button>
<div id="myDropDown" class="dropdown-content"></div>
</div>
`;
$('#movie').html(output);
})
.catch(function (error) {
console.log(error);
});
}
addFavorite.addEventListener('submit', (e) => {
e.preventDefault();
firebase.firestore().collection('favorites').add({
Title: addFavorite['movieid'].value
}).then(() => {
//close
console.log(addFavorite)
})
})
Not sure if I need to do another api call for this functionality or not. I did one api call to get a list of movies then another to get one movie. When the user goes to the one movie that is where I want the add favorite button. I hope someone knows how to lead me in the right direction. First time asking on Stackoverflow don't hurt me lol
i am taking simple ul list as example
<ul id="movie">
</ul>
<script>
// DUMMY records
const apiCallDataExample = [
{
id: 1,
name: "A"
},
{
id: 2,
name: "B"
},
{
id: 3,
name: "C"
}
];
let movies = [];
getMovie();
function getMovie() {
movies = apiCallDataExample; // You will call your API to get the data, and store it in upper scope 'movies' variable.
let htmlContent = ''; // prepare your html content -> in your case it is droup down i guess.
for (let movie of movies) {
htmlContent += `
<li>
<span> ${movie.name} </span>
<button onclick="addToFavourite(${movie.id})"> click me </button>
</li>
`
// Attach click event or any listener to get selected movie id or any identifier
}
let elem = document.getElementById("movie").innerHTML = htmlContent;
}
/**
* click event will trigger and we can fetch selected movie by given identifier, in my case it is `id `field.
*/
function addToFavourite(id) {
let selected_movie = movies.find(movie => movie.id === id); // find your movie by id.
console.log("selected movie is", selected_movie)
// add your data into collection as per your defined property , my case { id, name}.
/*
// Your fire base function
firebase.firestore().collection('favorites').add({
id: selected_movie.id,
name: selected_movie.name
}).then(() => { })
*/
}
</script>

How to translate text generated with javascript

So adminlte has the trans() function which works perfectly when its used in blade.php.
Lets say i have a form that if completed incorrectly throws a warning. I do the checking in js. And I want to have a pop up message that is displayed. The message need to be translatable.
What I tried is - in the php file make an array with the translatable text:
$returnArr = [
'titleSuccess' => trans('title.success'),
'titleWarning' => trans('title.warning')
];
Then retrieve it in the js and display the message.
$.post('/' + currentLanguage.locale + '/admin/page/error', {id:sId, note:note})
.done(function (result) {
if (result.status === 1) {
msg
.html(createAlert(result.titleSuccess, result.msg, 'success'))
.slideDown('fast');
} else {
msg
.html(createAlert(result.titleError, result.msg, 'danger'))
.slideDown('fast');
}
})
The problem is these keywords- title.warning, title.success are translated but in the default language that is set in the system. Not the one that the user has set.
Why is that happening? And is there a way to use trans() in js?

How do I populate a list field in a model from javascript?

I have a Kendo.MVC project. The view has a model with a field of type List<>. I want to populate the List from a Javascript function. I've tried several ways, but can't get it working. Can someone explain what I'm doing wrong?
So here is my model:
public class Dashboard
{
public List<Note> ListNotes { get; set; }
}
I use the ListNotes on the view like this:
foreach (Note note in Model.ListNotes)
{
#Html.Raw(note.NoteText)
}
This works if I populate Model.ListNotes in the controller when the view starts...
public ActionResult DashBoard(string xsr, string vst)
{
var notes = rep.GetNotesByCompanyID(user.ResID, 7, 7);
List<Koorsen.Models.Note> listNotes = new List<Koorsen.Models.Note>();
Dashboard employee = new Dashboard
{
ResID = intUser,
Type = intType,
FirstName = user.FirstName,
LastName = user.LastName,
ListNotes = listNotes
};
return View(employee);
}
... but I need to populate ListNotes in a Javascript after a user action.
Here is my javascript to make an ajax call to populate ListNotes:
function getReminders(e)
{
var userID = '#ViewBag.CurrUser';
$.ajax({
url: "/api/WoApi/GetReminders/" + userID,
dataType: "json",
type: "GET",
success: function (notes)
{
// Need to assign notes to Model.ListNotes here
}
});
}
Here's the method it calls with the ajax call. I've confirmed ListNotes does have the values I want; it is not empty.
public List<Koorsen.Models.Note> GetReminders(int id)
{
var notes = rep.GetNotesByCompanyID(id, 7, 7);
List<Koorsen.Models.Note> listNotes = new List<Koorsen.Models.Note>();
foreach (Koorsen.OpenAccess.Note note in notes)
{
Koorsen.Models.Note newNote = new Koorsen.Models.Note()
{
NoteID = note.NoteID,
CompanyID = note.CompanyID,
LocationID = note.LocationID,
NoteText = note.NoteText,
NoteType = note.NoteType,
InternalNote = note.InternalNote,
NoteDate = note.NoteDate,
Active = note.Active,
AddBy = note.AddBy,
AddDate = note.AddDate,
ModBy = note.ModBy,
ModDate = note.ModDate
};
listNotes.Add(newNote);
}
return listNotes;
}
If ListNotes was a string, I would have added a hidden field and populated it in Javascript. But that didn't work for ListNotes. I didn't get an error, but the text on the screen didn't change.
#Html.HiddenFor(x => x.ListNotes)
...
...
$("#ListNotes").val(notes);
I also tried
#Model.ListNotes = notes; // This threw an unterminated template literal error
document.getElementById('ListNotes').value = notes;
I've even tried refreshing the page after assigning the value:
window.location.reload();
and refreshing the panel bar the code is in
var panelBar = $("#IntroPanelBar").data("kendoPanelBar");
panelBar.reload();
Can someone explain how to get this to work?
I don't know if this will cloud the issue, but the reason I need to populate the model in javascript with an ajax call is because Model.ListNotes is being used in a Kendo Panel Bar control and I don't want Model.ListNotes to have a value until the user expands the panel bar.
Here's the code for the panel bar:
#{
#(Html.Kendo().PanelBar().Name("IntroPanelBar")
.Items(items =>
{
items
.Add()
.Text("View Important Notes and Messages")
.Expanded(false)
.Content(
#<text>
#RenderReminders()
</text>
);
}
)
.Events(e => e
.Expand("getReminders")
)
)
}
Here's the helper than renders the contents:
#helper RenderReminders()
{
if (Model.ListNotes.Count <= 0)
{
#Html.Raw("No Current Messages");
}
else
{
foreach (Note note in Model.ListNotes)
{
#Html.Raw(note.NoteText)
<br />
}
}
}
The panel bar and the helpers work fine if I populate Model.ListNotes in the controller and pass Model to the view. I just can't get it to populate in the javascript after the user expands the panel bar.
Perhaps this will do it for you. I will provide a small working example I believe you can easily extend to meet your needs. I would recommend writing the html by hand instead of using the helper methods such as #html.raw since #html.raw is just a tool to generate html in the end anyways. You can write html manually accomplish what the helper methods do anyway and I think it will be easier for you in this situation. If you write the html correctly it should bind to the model correctly (which means it won't be empty on your post request model) So if you modify that html using javascript correctly, it will bind to your model correctly as well.
Take a look at some of these examples to get a better idea of what I am talking about:
http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
So to answer your question...
You could build a hidden container to hold your list values like this (make sure this container is inside the form):
<div id="ListValues" style="display:none">
</div>
Then put the results your ajax post into a javascript variable (not shown).
Then in javascript do something like this:
$('form').off('submit'); //i do this to prevent duplicate bindings depending on how this page may be rendered futuristically as a safety precaution.
$('form').on('submit', function (e) { //on submit, modify the form data to include the information you want inside of your ListNotes
var data = getAjaxResults(); //data represents your ajax results. You can acquire and format that how you'd like I will use the following as an example format for how you could save the results as JSON data: [{NoteID ="1",CompanyID ="2"}]
let listLength = data.length;
for (let i = 0; i < listLength; i++) {
$('#ListValues').append('<input type="text" name="ListNotes['+i+'].NoteID " value="' + data.NoteID +'" />')
$('#ListValues').append('<input type="text" name="ListNotes['+i+'].CompanyID " value="' + data.CompanyID +'" />')
//for your ajax results, do this for each field on the note object
}
})
That should do it! After you submit your form, it should automatically model bind to you ListNotes! You will be able to inpsect this in your debugger on your post controller action.

Categories