Asyc Error on IE protractor - node.js

I'm currently trying to test the following pice of code:
<footer class="footer">
<div class="container">
<div class="row">
<form subscribe-directive="" ng-controller="SubscribeController" class="form col-xs-12 col-sm-8 col-md-6 col-lg-4 ng-scope ng-dirty ng-valid ng-valid-email">
<h3 class="footer__title text-uppercase margin-bottom-25">Sign up!</h3>
<div class="row">
<div class="col-sm-8 col-xs-7">
<input type="email" class="form-control ng-touched ng-dirty ng-valid ng-valid-email" ng-disabled="working || subscription.done" placeholder="Email Address" ng-model="subscription.email"> </div>
<div class="col-sm-4 col-xs-5">
<button ng-click="submit(subscription.email)" ng-disabled="working || !subscription.email || subscription.done" ng-class="{'working': working}" class="btn btn--inverse btn-red form-control" type="submit" disabled="disabled"> <span ng-bind-html="submitBtn" class="ng-binding">SUBSCRIBE</span> </button>
</div>
</div>
<p ng-show="callback_message" class="msg ng-binding ng-hide" ng-bind-html="callback_message"></p>
</form>
<nav class="col-xs-12 col-md-6 col-lg-offset-2">
<ul class="nav navbar-nav navbar-right margin-bottom-25">
<li>Press
</li>
<li>News
</li>
<li>Contact Us
</li>
<li><a target="_blank" href="//test.com/en">Test Project</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="footer__social-icon"> <a target="_blank" href="https://www.facebook.com/"><i class="fa fa-facebook"></i></a> </li>
<li class="footer__social-icon"> <a target="_blank" href="https://twitter.com/"><i class="fa fa-twitter"></i></a> </li>
<li class="footer__social-icon"> <a target="_blank" href="https://www.youtube.com/user/"><i class="fa fa-youtube"></i></a> </li>
</ul>
</nav>
</div>
<div class="row">
<div class="col-xs-12 col-sm-6 copy"> Privacy Policy
<br> Copyright © Test-inc. All Rights Reserved. </div>
<div class="col-xs-12 col-sm-6 text-right copy">
<br> Microsoft Ventures. Supported by Microsoft Ventures London Accelerator </div>
</div>
</div>
</footer>
But when I do the following actions:
it('User should see a message that he has already been added to the campaing when entering the same email twice', function () {
browser.executeScript("window.scrollBy(0,10000)");
basePage.email.sendKeys('bruno#test.com');
basePage.subscribe.click().then(function () {
browser.sleep(7000);
basePage.confirmMessage('Contact already added to target campaign');
});
On my basePage I've:
//this.email = element(by.model('subscription.email'));
this.email = element(by.xpath('/html/body/footer/div/div[1]/form/div/div[1]/input'));
this.waitlistBtn = element.all(by.binding('submitBtn'));
this.subscribe = element(by.buttonText('SUBSCRIBE'));
I keep getting the follwing error (I'm running it against BrowserStack):
Failures:
1) New Landing page module verification --> User should be correctly added to the update list
Message:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Stack:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
at Timer.listOnTimeout (timers.js:110:15)
Here's my part of my configuration:
{
name: testName,
browserName: 'IE',
browser_version: '11.0',
os: 'Windows',
os_version: '8.1',
resolution: '2048x1536',
'browserstack.user': browserstackUser,
'browserstack.key': browserstackKey,
'browserstack.debug': 'true',
'browserstack.selenium_version': '2.45.0',
'browserstack.ie.driver': '2.44',
ignoreProtectedModeSettings: true
}
onPrepare: function () {
jasmine.getEnv().addReporter(reporter);
browser.driver.manage().window().maximize();
global.dvr = browser.driver; //variable to call selenium directly
global.isAngularSite = function (flag) {
browser.ignoreSynchronization = !flag; //This setup is to configure when testing non-angular pages
};
//browser.manage().timeouts().pageLoadTimeout(90000);
browser.manage().timeouts().implicitlyWait(100000);
}
I must clarify that it does not happen with other test for IE, it just happens with this part that's located at the footer of the page.
Can you please help? do you have any suggestion? or what can you see that I'm doing wrong?
Thanks.-

Since I had many problems to avoid the ASync, I've decided that for this particular scenario to avoid IE! I've done the following:
it('User should see a message that he has already been added to the campaing when entering the same email twice', function () {
browser.getCapabilities().then(function (capabilities) {
browser = capabilities.caps_.browserName;
platform = capabilities.caps_.platform;
}).then(function () {
console.log('Browser:', browser, 'on platform', platform);
if (browser == 'internet explorer') {
console.log('IE Was avoided for this test.');
} else {
basePage.email.sendKeys('bruno#test.com');
console.log('Mande el mail');
basePage.subscribe.click().then(function () {
basePage.confirmMessage('Contact already added to target campaign');
});
}
});
});
Please, if anyone reading this comes up with a better solution, please post.

Related

error in nodejs using sripe for payment for website

I am implementing a payment method in my e-commerce website using stripe and node.js , and I am not using a database only using JSON files to add my items to the website, but I am getting errors in ejs file. for rendering the page I used the fs module in node js. I wanted to know where I can define the items in ejs , or server , or HTML file
''' shop.ejs'''
<div class="box-container">
<% items.products.forEach(function(item){ %>
<div class="box" data-item-id="<%= item.id %>">
<div class="icons">
</div>
<img class="image" src="/image/<%= item.imgName %>" alt="">
<div class="content">
<div class="price"> &#8377 <%= item.price %></div>
<h3 class="shop-item-title"><%= item.name %></h3>
<div class="stars">
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="far fa-star"></i>
<span> (50) </span>
</div>
</div>
</div>
<% }) %>
'''server.js'''
app.get('/shop', function(req, res){
fs.readFile('items.json', function(error, data){
if(error){
res.status(500).end()
}else {
res.render('shop.ejs', {
items: JSON.parse(data)
})
}
})
})
'''error'''
>> 172| <% items.products.forEach(function(item){ %>
173| <div class="box-container" data-item-id="<%= item.id %>">
174| <div class="box">
175| <div class="icons">
items are not defined
Did you pass the items data object to the ejs render function?

How to load comments without refreshing the page in nodeJs and Ajax

The actual challenge that I am facing now is how to load the comment properly. My Ajax is creating the comment but I am struggling to load the comment properly in line with other comments.
what happening now is that the comment loads but it doesn't load properly, I am struggling to load it with the right ID in the right place. when it loads, it shows my title and descriptions together and it doesn't load the date.
<div class="container">
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<h1>Comment App</h1>
<form action="/programs/<%= program._id %>/createComment" method="POST" >
<div class="form-group">
<input name="name" id="username" class="form-control" placeholder="username">
</div>
<div class="form-group">
<textarea name="description" id="descriptioncomment" class="form-control" placeholder="comment"></textarea>
</div>
<div class="form-group">
<input type="submit" id="post-comment" class="btn btn-primary" value="Submit">
</div>
</form>
<ul id="commentList" class="list-group">
</ul>
</div>
</div>
</div>
<section class="content-item" id="comments">
<div class="row" id="comment-lists" >
<div class="col-sm-10" >
<h3 id="comments-count" ><%= program.programcomments.length%> </h3>
<% program.programcomments.forEach(comments=> { %>
<div class="media" >
<div class="media-body" >
<h4 class="media-heading" id="lists" ><%= comments.name %></h4>
<p id="lists" ><%=comments.description %></p>
<ul class="list-unstyled list-inline media-detail pull-left" id="lists">
<li id="lists"><i class="fa fa-calendar" ></i><%= moment(comments.createdAt).format('llll') %></li>
</ul>
</div>
</div>
<% });%>
</div>
</div>
</section>
$('#post-comment').on('click', function(event) {
event.preventDefault();
$.ajax({
url : "/programs/<%= program._id %>/createComment",
method : 'POST',
data : {
name : $('#username').val(),
description : $('#descriptioncomment').val()
},
success : function(result ) {
$('.form-control').each(function () {
let comments = this.value;
$('#comment-lists').append($('#lists').text(comments))
document.getElementById('comments-count').innerHTML++
});
$("#username").val('');
$("textarea#descriptioncomment.form-control").val('');
}
});
})
You are using same ids for mutliple elements so first remove them and use class. Then , you can generate entire media div inside success function of ajax with the value of inputs and then append them inside your comment-lists div.
Demo Code :
$('#post-comment').on('click', function(event) {
event.preventDefault();
/*$.ajax({
url: "/programs/<%= program._id %>/createComment",
method: 'POST',
data: {
name: $('#username').val(),
description: $('#descriptioncomment').val()
},
success: function(result) {*/
//append new div .. with username & desc
$('#comment-lists').append(`<div class="media">
<div class="media-body">
<h4 class="media-heading">${$('#username').val()}</h4>
<p class="lists">${$('#descriptioncomment').val()}</p>
<ul class="list-unstyled list-inline media-detail pull-left lists">
<li><i class="fa fa-calendar"></i>${moment(new Date()).format('llll') }</li>
</ul>
</div>
</div>`)
$("#comments-count").text(parseInt($("#comments-count").text()) + 1) //updated total
//then emtpy
$("#username").val('');
$("textarea#descriptioncomment.form-control").val('');
/*}
});*/
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<div class="container">
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<h1>Comment App</h1>
<form action="/programs/<%= program._id %>/createComment" method="POST">
<div class="form-group">
<input name="name" id="username" class="form-control" placeholder="username">
</div>
<div class="form-group">
<textarea name="description" id="descriptioncomment" class="form-control" placeholder="comment"></textarea>
</div>
<div class="form-group">
<input type="submit" id="post-comment" class="btn btn-primary" value="Submit">
</div>
</form>
<ul id="commentList" class="list-group">
</ul>
</div>
</div>
</div>
<section class="content-item" id="comments">
<div class="row" id="comment-lists">
<div class="col-sm-10">
<h3 id="comments-count">2</h3>
<div class="media">
<div class="media-body">
<h4 class="media-heading">Abc</h4>
<p class="lists">Descp xyz</p>
<ul class="list-unstyled list-inline media-detail pull-left lists">
<li><i class="fa fa-calendar"></i>23-2-2022</li>
</ul>
</div>
</div>
<div class="media">
<div class="media-body">
<h4 class="media-heading lists">Abc</h4>
<p class="lists">Descp xyz</p>
<ul class="list-unstyled list-inline media-detail pull-left lists">
<li><i class="fa fa-calendar"></i>23-2-2022</li>
</ul>
</div>
</div>
</div>
</div>
</section>

case with router-outlet in Angular

This is my case, I have a main login that I configure in my app-routing.module.ts
{
path:'',
redirectTo:'/login',
pathMatch: 'full'
},
{
path:'users',
component:UsuariosComponent
}
my login
<div class="container p-5">
<div class="row">
<div class="col-md-4 mx-auto">
<div class="card">
<div class="card-header">
Acceso al Sistema
</div>
<div class="card-body">
<form (submit)="login()" >
<div class="form-group">
<input type="text" [(ngModel)]="user.email" name="email" class="form-control" placeholder="Email" autofocus>
</div>
<div class="form-group">
<input type="password" [(ngModel)]="user.contrasenia" name="password" class="form-control" placeholder="Contraseña" >
</div>
<button type="submit" class="btn btn-primary btn-block">
Ingresar
</button>
</form>
</div>
</div>
</div>
</div>
</div>
then when logging in to the main component use route.navigate to / main
my app.component is like this
< router-outlet></router-outlet>
2.my main is like this main.component.html
<ul class="navbar-nav ml-auto"><!--mr-auto-->
<li class="nav-item">
<a class="nav-link" routerLink="/users" routerLinkActive="active">
<i class="material-icons">person</i>
</a>
</li>
<li class="nav-item">
<a class="nav-link" style="cursor: pointer;" (click)="salir()" routerLinkActive="active">
<i class="material-icons">power_settings_new</i>
</a>
</li>
</ul>
<router-outlet></router-outlet>
my problem comes here when I want to access the routerlink /users, the nav or the ul where the routerlink had did not load, it takes me practically to another page, help me pls
Router-outlet only works for child routes. You need to have something like:
{
path:'',
component: Maincomponent,
children:[
{
path: 'users',
component: Usercomponent
}
]
}
And the router-outlet must be located in the parent Maincomponent html file

Dynamic Tab + bootstrap + angular5

I am new to Front-End and angular part. I need to load tabs dynamically from what it returned from Backend...
Consider i am getting an array as like below :
*["tab1","tab2","tab3"].*
I have show tabs in a page with tab1, tab2, tab3.
What i have tried is hardcoded , its working,
<div class="nav-tabs-custom">
<ul class="nav nav-tabs" >
<li class="active"><b>tab1</b></li>
<li><b>tab2</b></li>
<li><b>tab3</b></li>
<li><b>tab4</b></li>
</ul>
</div>
<div class="tab-content">
<div class="tab-pane active" id="tab_1"> </div>
<div class="tab-pane active" id="tab_2"> </div>
<div class="tab-pane active" id="tab_3"> </div>
<div class="tab-pane active" id="tab_4"> </div>
</div>
Also i have to make sure that on click of the tab it should call a method with clicked name. All should be dynamic. Please suggest your ideas.Thanks.
you have to change href="#id" to data-target="#id"
<div class="nav-tabs-custom">
<ul class="nav nav-tabs" >
<li class="active"><a data-target="#tab_1" data-toggle="tab" (click)="loadData('abc')"><b>tab1</b></a></li>
<li><a data-target="#tab_2" data-toggle="tab" (click)="loadData('xxx')"><b>tab2</b></a></li>
<li><a data-target="#tab_3" data-toggle="tab" (click)="loadData('xyz')"><b>tab3</b></a></li>
<li><a data-target="#tab_4" data-toggle="tab" (click)="loadData('fgfgfg')"><b>tab4</b></a></li>
</ul>
</div>
<div class="tab-content">
<div class="tab-pane active" id="tab_1"> </div>
<div class="tab-pane active" id="tab_2"> </div>
<div class="tab-pane active" id="tab_3"> </div>
<div class="tab-pane active" id="tab_4"> </div>
</div>
I achieved such functionality using ngx-Bootstrap
Array of tabs:
tabs: any[] = [{
title: 'Dynamic Title 1',
content: 'Dynamic content 1'
},
{
title: 'Dynamic Title 2',
content: 'Dynamic content 2'
},
{
title: 'Dynamic Title 3',
content: 'Dynamic content 3',
removable: true
}
];
Display tabs:
<tabset>
<tab heading="Static title">Static content</tab>
<tab *ngFor="let tabz of tabs"
[heading]="tabz.title"
[active]="tabz.active"
(select)="tabz.active = true"
[disabled]="tabz.disabled"
[removable]="tabz.removable"
(removed)="removeTabHandler(tabz)"
[customClass]="tabz.customClass">
{{tabz?.content}}
</tab>
</tabset>
Check full usage here.
So, there are different ways of implementing it. One way as suggested by #Comann will definitely work. The other way of doing the same thing would be installing bootstrap dependency - try doing
npm install --save bootstrap
Import this in your styles.css file
#import '~bootstrap/dist/css/bootstrap.css';
You can also import it in your angular.json file assuming you might have generated the project using angular-cli. I prefer it to be in styles.css.
Create a separate navbar component and in the template
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" routerLink="/route1">Route1<span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/route2">Route 2</a>
</li>
</ul>
</div>
</nav>
<router-outlet></router-outlet>
Instead of having the two router links hard coded you will loop around with *ngFor on the array of tabs and populate it. Hope this helps.

I want to give 'class = active' attribute with Meteor + semantic UI

<template name="menu">
<div class="ui grid">
<div class="two wide column"></div>
<div class="twelve wide column">
<div class="ui red menu">
<a class="{{active}} item" id="home">
<i class="home icon"></i> Péng you
</a>
<a class="item" id="message">
<i class="mail icon"></i> Message
</a>
<a class="item" id="friend">
<i class="user icon"></i> Find Friend
</a>
<div class="right red menu">
<a class="active item">
<i class="sign in icon"></i> Log In
</a>
</div>
</div>
</div>
<div class="two wide column"></div>
</div>
Template.menu.helpers({
'active': function (e, tmpt) {
var active = Session.get('activeMake');
return active
}
});
Template.menu.events({
'click #home': function (e, tmpt) {
event.preventDefault();
var activeAttribute = "active";
Session.set('activeMake', activeAttribute);
}
});
now, I can give active. but, I can't delete active when user cluck other menu.
and i think there is much better way to do this. (ex: without session or ID attribute)
please help me....
its an old question, iam having same trouble, this works but is not the perfect way. In my case i got like 5 elements so it work fast, but in other app i got like 300 buttons and works a litle slow in cordova app, specially olds tablets.
Template.yourtTemplateName.events({
'click .commonClass': function (e, t) {
$(".commonClass").each(function () {
console.log(this);
$(this).removeClass('active')
});
$(e.target).addClass('active')
},
});

Resources