I've trying click at my element which it is on a side menu, after the click, the system opens a new window, which is like a frame.
But, using Xpath, protractor clicks at the element (I can see it because the element turns yellow when the mouse is houver) but the windown doesn't open.
I think protractor is click at the wrong place.
How can fix it?
the HTML:
<ul style="margin:10px 0 0 0; padding: 0">
<li class="menu-content-item ng-star-inserted" title="Principal">
<a class="ng-star-inserted">
<i class="" data-first="P"></i>
<span class="sidebar-title-menu"> Principal </span>
<i class="zmdi zmdi-chevron-right"></i>
</a>
</li>
</ul>
I already tried:
browser.driver.manage().window().maximize();
and
const menuPrincipal = element(by.css('div[title=Principal]'));
I'm using protractor helper so my code is like this:
async entraNoMeucomOLink() {
try {
const menuPrincipal = element(by.xpath('/html/body/application/pjmt-layout/div[1]/pjmt-bar/div/pjmt-menu-vertical/div[1]/div/ul/li/a/');
protractorHelper.waitForElementVisibility(menuPrincipal, 'MENU PRINCIPAL NAO ESTA VISIVEL', 5000);
browser.actions().mouseMove(elemento).click().perform();(menuPrincipal)
}
The element is like this :
It's not clear what you want. I change your code. Try this one and give feedback, please)
async entraNoMeucomOLink() {
const menuPrincipal = $('.sidebar-title-menu');
protractorHelper.waitForElementVisibility(menuPrincipal, 'MENU PRINCIPAL NAO ESTA VISIVEL', 5000);
await menuPrincipal.click();
}
Related
I'm fairly new to Angular and need to solve what seems to be a simple problem: show an alert or confirmation message on navigating between tabs in angular bootstrap. the issue is when moving to another tab, the tab will open first and then show an alert message if clicked on cancel it will back to the previous tab, what I want simply is to not leave the current tab until click on confirmation to leave.
<ul ngbNav #navWithIcons="ngbNav" [(activeId)]="activeTab" class="nav-tabs">
<li ngbNavItem="docs">
<a ngbNavLink (click)="navigateTab('docs')">
<span [data-feather]="'file-text'"></span>Documents</a>
<ng-template ngbNavContent>
<p>
any content
</p>
</ng-template>
</li>
<li ngbNavItem="external">
<a ngbNavLink (click)="navigateTab('external')">
<span [data-feather]="'chrome'"></span> External
Resource</a>
<ng-template ngbNavContent>
<p>
any external link
</p>
</ng-template>
</li>
</ul>
<div [ngbNavOutlet]="navWithIcons" class="mt-2"></div>
TS:
navigateTab(navTab: string) {
if (navTab != this.currentTab) {
if (this.isInputUpdated) {//if there is an update on the current tab inputs then
this.confirmationMessage(true, this.currentTab);
this.isInputUpdated = false;
}
this.currentTab = navTab;
}
}
You can listen to navChange event on the ngbNav element and stop the event from propagating
<ul ngbNav #navWithIcons="ngbNav" [(activeId)]="activeTab" class="nav-tabs" (navChange)="navChanged($event)">
...
</ul>
navChanged(event) {
event.preventDefault()
}
Inside the confirmationMessage method, if clicked on confirm set active tab with the value of currentTab
This code will replace what is shown inside <button></button> with selected icon from dropdown list.
This works good, only problem is that after clicking on selected element, icon inside that element will for some reason disappear? Why does this happen? I want <li> to be unchanged
http://codepen.io/filaret/pen/PGJEAL
HTML:
<div class="input-group-btn">
<button type="button" class="btn" data-toggle="dropdown">
<i class="fa fa-book"></i>
</button>
<ul class="dropdown-menu">
<li><i class="fa fa-book"></i> Something 111</li>
<li><i class="fa fa-newspaper-o"></i> Something 2222</li>
</ul>
</div>
jQuery:
var $selectWrapper = $('.input-group-btn');
$selectWrapper.find(".dropdown-menu li").click(function() {
// Get <i class="fa"></i>
var $selectedIcon = $(this).find('.fa');
// Put it inside <button></button>
$selectWrapper.find(".btn").html($selectedIcon);
});
You need to clone the icon using clone() like following
var $selectedIcon = $(this).find('.fa').clone();
instead of
var $selectedIcon = $(this).find('.fa');
UPDATED CODEPEN
Otherwise since you have i tag in dropdown and button tag and that only class change, why don't you just copy the class, it's more efficient, faster and easy to understand in your code.
jQuery(document).ready(function($) {
"use strict";
var $selectWrapper = $('.input-group-btn');
var $buttonIcon = $('.btn i');
$selectWrapper.find(".dropdown-menu li").click(function() {
// Get <i class="fa"></i>
var $selectedIcon = $(this).find('.fa');
// get icon classes
var classes = $selectedIcon.attr("class");
// Put the class in the button i tag
$buttonIcon.attr('class', classes);
});
});
See code pen: http://codepen.io/anon/pen/ORxQPZ
This is my popover that pops up once you hover over it:
This is how the html looks before the popover is added to the DOM:
<span
tariff-popover="popover.car2go.airport"
class="ng-isolate-scope">
<span ng-transclude="">
<span class="ng-binding ng-scope">
Airport Fee
</span>
</span>
<span
popover-placement="right"
uib-popover-html="text"
popover-trigger="mouseenter"
class="fa fa-info-circle">
</span>
</span>
This is after the popover is visible:
<span
tariff-popover="popover.car2go.airport"
class="ng-isolate-scope">
<span ng-transclude="">
<span class="ng-binding ng-scope">
Airport Fee
</span>
</span>
<span
popover-placement="right"
uib-popover-html="text"
popover-trigger="mouseenter"
class="fa fa-info-circle">
</span>
<div
tooltip-animation-class="fade"
uib-tooltip-classes=""
ng-class="{ in: isOpen() }"
uib-popover-html-popup=""
title=""
content-exp="contentExp()"
placement="right"
popup-class=""
animation="animation"
is-open="isOpen"
origin-scope="origScope"
style="visibility: visible; display: block; top: -41px; left: 108.984px;"
class="ng-isolate-scope right fade popover in">
<div class="arrow">
</div>
<div class="popover-inner">
<!-- ngIf: title -->
<div
class="popover-content ng-binding"
ng-bind-html="contentExp()">
4,90€ for all rides to and from the airport
</div>
</div>
</div>
</span>
I want to test if the text is not empty. In my test I'm checking that there is a string like 4,90€ for all rides to and from the airport. This string must not be empty.
This is part of my protractor-conf with the regex to check if the element is not empty and how long the browser should wait before the check:
params: {
regexNotEmpty: '^(?!\s*$).+',
sleepTimeout: 1000
},
This is my protractor test:
describe('car2go test all input fields and checkboxes', function() {
beforeEach(function() {
browser.get('http://localhost:9999/#/car2go');
browser.waitForAngular();
});
it('should display the popover-content on mouseover', function() {
var path = 'span[tariff-popover="popover.car2go.airport"]';
var pathIcon = path + ' > .fa.fa-info-circle';
var pathPopover = path + ' > .popover.ng-isolate-scope.right.fade.in';
var popoverIcon = element(by.css(pathIcon));
browser.actions().mouseMove(popoverIcon).perform();
var popover = element(by.css(pathPopover));
expect(popover.isDisplayed()).toBeTruthy();
browser.sleep(browser.params.sleepTimeout);
expect(popover.getText()).toMatch(browser.params.regexNotEmpty);
});
});
I'm hovering over the i icon and checking if the popover appears. No problem. Then I have to wait for 1 second until the popover is fully loaded and I can check if it is not empty.
The problem with this approach is it works mostly in Chrome, but not in Firefox which is slower. How can the test be done similar to a promise? Can protractor wait for like 5 seconds and if there is no text, mark the test as failure?
Can protractor wait for like 5 seconds and if there is no text, mark the test as failure?
This is what the browser.wait() is all about. It is also generally recommended as opposed to using browser.sleep(). We've even enforced the "not use browser.sleep()" rule with the help of eslint-plugin-protractor.
In your case, textToBePresentInElement fits perfectly:
var EC = protractor.ExpectedConditions;
browser.wait(EC.textToBePresentInElement(popover, "text to expect"), 5000);
Protractor would wait up to 5 seconds constantly checking if the text is present in element. If after the 5 seconds the text would not be there - you will get an error and the test would fail.
If needed, you may also use the visibilityOf expected condition for the "wait until the popover appears" part.
If you need to wait for a test that matches a specific regular expression pattern, you can make a custom Expected Condition:
var EC = protractor.ExpectedConditions;
var patternToBePresentInElement = function(elementFinder, pattern) {
var matchesPattern = function() {
return elementFinder.getText().then(function(actualText) {
return actualText.search(pattern) !== -1;
});
};
return EC.and(EC.presenceOf(elementFinder), matchesPattern);
};
Usage:
browser.wait(patternToBePresentInElement(popover, /\w+/), 5000);
I have a dynamically created 3 options list which are attached at the end of a table row. I want to hide or disable Edit and Copy options if certain conditions are not met when page loads. How can i do this using either jQuery of JavaScript.
<div class="btn-group ewButtonGroup open">
<button class="dropdown-toggle btn btn-small" data-toggle="dropdown" href="#">Options <b class="caret"></b></button>
<ul class="dropdown-menu ewMenu">
<li><a class="ewRowLink ewView" data-caption="View" href="teamsview.php?showdetail=&TeamID=1">View</a></li>
<li><a class="ewRowLink ewEdit" data-caption="Edit" href="teamsedit.php?TeamID=1">Edit</a></li>
<li><a class="ewRowLink ewCopy" data-caption="Copy" href="teamsadd.php?TeamID=1">Copy</a>
</li>
</ul>
</div>
I have tried the following code which deosnt work.
<script>
$(document).ready(function() {
var Week_Check = $('#ewRowLink ewView span').text();
if ( Week_Check > 10) {
$('.ewRowLink ewView').hide();
}
});
</script>
You have a bad jQuery selector. If you want to hide an element having both of those classes you want to go this way:
$('.ewRowLink.ewView').hide();
By using $('.ewRowLink ewView').hide(); you basically state: hide all ewView (?) elements that are inside other elements having ewRowLink class.
You can use .off() to unbind the event:
$('.ewEdit, .ewCopy').off('click');
or if you want to hide:
$('.ewEdit, .ewCopy').hide();
Yet you need to mention on what condition you want to do this.
<script>
$(document).ready(function() {
var Week_Check = $('#ewRowLink, #ewView').find('span').html();
if ( Week_Check > 10) {
$('.ewRowLink, .ewView').hide();
}
});
</script>
I have a listing of articles here, and I can't figure out how to execute the ng-click function calls on every new article inside the ng-repeat. Right now it works for existing articles, but when new articles are added dynamically (via AJAX), I need those to have the same functionality too.
For example: the ng-click function calls on the "+" sign to reveal social buttons seem to not work once new articles are inserted via AJAX (ie: delete articles, and let list be populated again with new elements)
Does AngularJS provide any tools to do that?
<div>
<div>
<input type="text" ng-model="search">
<span>{{filtered.length}} article(s)</span>
</div>
<div article-listing ng-repeat="article in filtered = (wikiArticles | filter:search)">
<!--Individual article begin-->
<span>
{{article.title}}
</span>
<div>
<a ng-click="articles.removeArticle($index)" title="Delete">
<span>✖</span>
</a>
<a ng-click="articles.toggleShare(article)">
<span class="plus-sign" title="Share">✖</span>
<div social-share ng-show="article.socialShare">
<div ng-click="socialShare = !socialShare" class="addthis_toolbox addthis_default_style addthis_32x32_style"
addthis:title="{{article.title}}" addthis:description="{{article.extract}}" addthis:url="{{article.url}}">
<a class="addthis_button_facebook"></a>
<a class="addthis_button_twitter"></a>
<a class="addthis_button_google_plusone_share"></a>
<a class="addthis_button_reddit"></a>
<a class="addthis_button_hackernews"></a>
</div>
</div>
</a>
</div>
<div>{{article.extract}}</div>
<!--Individual article end-->
</div>
</div>
Code for ng-click calls that don't seem to work for new article insertions
$scope.articles = (function() {
return {
shuffleArticles : function() {
$scope.wikiArticles.reverse();
},
removeArticle : function(index) {
$scope.wikiArticles.splice(index, 1);
$scope.fireAPICalls();
},
toggleShare : function(currArticle) {
var previousState = currArticle.socialShare;
angular.forEach($scope.wikiArticles, function(article) {
article.socialShare = false;
});
currArticle.socialShare = previousState ? false : true;
}
}
})();
Your ng-click calls are actually working- you can watch the ng-show toggle in the debugger.
The problem is that there is nothing to display on the new items you add.
The articles you initially add all have their icons populated with the .addthis classes, for instance here's your Facebook icon element:
<a class="addthis_button_facebook at300b" title="Facebook" href="#">
<span class=" at300bs at15nc at15t_facebook">
<span class="at_a11y">Share on facebook</span>
</span>
</a>
at300bs includes the following css which displays the image:
background: url(widget058_32x32.gif) no-repeat left!important;
However as you add new items, you aren't including the needed .addthis classes to them. Their elements look like this:
<a class="addthis_button_facebook"></a>
So ng-show has nothing to display (it shows a 0x0 div).
Add the .addthis classes to your new elements as you add them and you'll be all set.