Wait until an element becomes visible using selenium-webdriver and PjantomJS - javascript

I am writing my automated test scripts using selenium-webdriver, phantomJS and mocha.
My script file is javascript file by nature.
I want to wait till an element(<a>) becomes completely visible. After it becomes visible, the element will be clicked.
Let me explain in details:
There are some menus and submenus. The menu is collapsible in nature. When I click on a menu, then its corresponding submenus are displayed.
My following script first iterates(And clicks) through the menu and then iterates and displays the submenu status.
for(var iMajor = 2; iMajor <= majorLinkLast ; iMajor++)
{
majorMenuXPath = "//ul[contains(#id, 'side-menu')]/li["+iMajor+"]/a";
if(iMajor != 2)
{
driver.findElement(By.xpath(majorMenuXPath)).click();
driver.manage().timeouts().implicitlyWait(30 * 10000);
}
for(var iMinor = 1; iMinor <= minorSize[iMajor] ; iMinor++)
{
minorMenuXPath = "//ul[contains(#id, 'side-menu')]/li["+iMajor+"]/ul/li["+iMinor+"]/a";
driver.findElement(By.xpath(minorMenuXPath)).isDisplayed().then(function(elem){
console.log(elem);
});
}
The above code displays the status of the submenus like:
true
true
true
true
true
true
true
false
true
false
true
false
true
false
false
true
true
true
true
true
true
true
true
true
true
I have used implicit method for making the driver wait. But still some submenus are displayed as false(means they are not visible). They should have been visible after the parent menu got clicked.
I need some help regarding the following:
How can I wait till the submenu is visible? After each submenu
becomes visible, I need to perform some action.
Or, how can I make the submenu visible after a particular time.
Here is my HTML:
<ul id="side-menu" class="nav">
<li class="nav-header">
<img class="logo" alt="Track Revenue" src="/images/3c4939d.png">
<div class="logo-element"> TR </div>
</li>
<li class="">
<a href="#home">
<i class="fa fa-bolt"></i>
<span class="nav-label">Tr Admin Menu</span>
<span class="fa arrow"></span>
</a>
<ul class="nav nav-second-level collapse" aria-expanded="false" style="height: 0px;">
<li>
All Users
</li>
<li>
All Companies
</li>
<li>
Devices
</li>
<li>
Send Email
</li>
<li>
Impersonate User
</li>
<li>
Test Encryption
</li>
</ul>
</li>
<li class="">
<a href="#home">
<i class="fa fa-th-large"></i>
<span class="nav-label">Campaigns</span>
<span class="fa arrow"></span>
</a>
<ul class="nav nav-second-level collapse" aria-expanded="false" style="height: 0px;">
<li>
Overview
</li>
<li>
CPC Update
</li>
<li>
SubID Update
</li>
<li>
Add Campaign
</li>
</ul>
</li>
<li>
<a href="#home">
<i class="fa fa-bar-chart-o"></i>
<span class="nav-label">Stats</span>
<span class="fa arrow"></span>
</a>
<ul class="nav nav-second-level collapse">
<li>
Campaign Stats
</li>
<li>
Week / Day Parting Stats
</li>
</ul>
</li>
<li>
<a href="#home">
<i class="fa fa-files-o"></i>
<span class="nav-label">Reports</span>
<span class="fa arrow"></span>
</a>
<ul class="nav nav-second-level collapse">
<li>
Custom Data Reports
</li>
<li>
SubID Analysis Report
</li>
<li>
Scheduled Reports
</li>
</ul>
</li>
<li>
<a href="#home">
<i class="fa fa-cog"></i>
<span class="nav-label">Settings</span>
<span class="fa arrow"></span>
</a>
<ul class="nav nav-second-level collapse">
<li>
Account
</li>
<li>
Plan Management
</li>
<li>
Campaign Groups
</li>
<li>
Affiliate Networks
</li>
<li>
Traffic Source
</li>
<li>
Manage Users
</li>
<li>
Manage Company
</li>
<li>
Blocking & Filter Rules
</li>
<li>
Domains
</li>
<li>
Campaign Maintenance
</li>
</ul>
</li>
</ul>
Note:
I am new to selenium. I need javascript procedure to solve the problem. I have no knowledge in JAVA or Python or C#
Can somebody help me please?

It is invisible for a reason, isn't it? Automate whatever a normal user would do to make that element visible. Sometimes sections of a page are hidden, because it there are multiple "views" on a single page. A user can usually navigate between those views by clicking on something or filling out forms. You have to automate the same interaction a user would do.

The following snippet helped the elements to get displayed.
minorMenuXPath = "//ul[contains(#id, 'side-menu')]/li["+iMajor+"]/ul/li["+iMinor+"]/a";
//Following snippet is stated for making the driver wait till the element is visble.
driver.wait(function()
{
return driver.isElementPresent(By.xpath(minorMenuXPath));
}, 20*1000);
driver.findElement(By.xpath(minorMenuXPath)).then(function(elem)
{
elem.isDisplayed().then(function(stat){
console.log(stat);
});
});

Related

Sidebar Functionality using jquery

Here is the code of the sidebar :
$('.sidebar-nav-menu,sidebar-nav-submenu').click(function(){
$(this).toggleClass('open');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sidebar-alt">
<div class="sidebar-content">
<ul class="sidebar-nav">
<li>
<i class="fa fa-dashboard sidebar-nav-icon"></i><span class="sidebar-nav-mini-hide">Dashboard</span>
</li>
<li>
<i class="fa fa-chevron-left sidebar-nav-indicator sidebar-nav-mini-hide"></i><i class="fa fa-cogs sidebar-nav-icon"></i><span class="sidebar-nav-mini-hide">Advanced Settings</span>
<ul>
<li>
Site Settings
</li>
<li>
Appearance
</li>
<li>
Login & Registration Settings
</li>
<li>
Session Settings
</li>
<li>
Mailer Settings
</li>
</ul>
</li>
<li class="active">
<i class="fa fa-chevron-left sidebar-nav-indicator sidebar-nav-mini-hide"></i><i class="fa fa-rocket sidebar-nav-icon"></i><span class="sidebar-nav-mini-hide">User Interface</span>
<ul>
<li>
Widgets
</li>
<li>
<i class="fa fa-chevron-left sidebar-nav-indicator"></i>Elements
<ul>
<li>
Blocks & Grid
</li>
<li>
Typography
</li>
<li>
Buttons & Dropdowns
</li>
<li>
Navigation & More
</li>
<li>
Progress & Loading
</li>
<li>
Tables
</li>
</ul>
</li>
<li>
<i class="fa fa-chevron-left sidebar-nav-indicator"></i>Forms
<ul>
<li>
Components
</li>
<li>
Wizard
</li>
<li>
Validation
</li>
</ul>
</li>
<li class="active">
<i class="fa fa-chevron-left sidebar-nav-indicator"></i>Icon Packs
<ul>
<li>
Font Awesome
</li>
<li>
Glyphicons Pro
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
WHAT I WANT
On clicking the a tag having class 'sidebar-nav-menu' it adds the 'open' class to the a tag and shows the first level of ul.
On clicking the a tag having class 'sidebar-nav-submenu' it adds the 'open' class to the a tag and shows the second level of ul.
Now i want to close all other second level 'sidebar-nav-submenu' if i open one second level 'sidebar-nav-submenu'.
Also if i open 1st level 'sidebar-nav-menu' then it should hide all other 'sidebar-nav-menu'
Any idea?
If I understand correctly, you can check to see if the (sub)menu is already open and if it is not then remove the class open from all other (sub)menus.
Edited the click submenu
$('.sidebar-nav-menu,.sidebar-nav-submenu').click(function() {
if (!$(this).hasClass('open')) {
if ($(this).hasClass('sidebar-nav-menu')) {
$('.sidebar-nav .sidebar-nav-menu .sidebar-nav-submenu.open').removeClass('open');
$('.sidebar-nav .sidebar-nav-menu.open').removeClass('open');
} else if ($(this).hasClass('sidebar-nav-submenu')) {
$('.sidebar-nav .sidebar-nav-submenu.open').removeClass('open');
}
}
$(this).toggleClass('open');
});
Let me know if this helps.

Add another level - side menu HTML/Boostrap 3/JS

How can I add another level to this menu structure from the HTML at the bottom of the page?
Current
Test
--->a
--->b
what I'm trying to do
Test
--->a
--->1
--->2
--->b
--->1
--->2
html
<li class="nav-header">
<a data-target="#menu5" data-toggle="collapse" href="#">
<h3>test</h3></a>
<ul class="list-unstyled collapse" id="menu5">
<li>
<i class="glyphicon glyphicon-circle"></i> Facebook
</li>
<li>
<i class="glyphicon glyphicon-circle"></i> Twitter
</li>
</ul>
</li>
<ul>
<li class="nav-header">
<a data-target="#menu5" data-toggle="collapse" href="#">
<h3>test</h3></a>
<ul class="list-unstyled collapse" id="menu5">
<li>
<a data-target="#submenu" data-toggle="collapse" href="#"><i class="glyphicon glyphicon-circle"></i> Facebook</a>
<ul class="list-unstyled collapse" id="submenu">
<li> 1 </li>
<li> 2</li>
</ul>
</li>
<li>
<i class="glyphicon glyphicon-circle"></i> Twitter
</li>
</ul>
</li>
</ul>
I believe you just need to create another collapse element with a unique Id. using the <a> element as your toggle.

Add Class to one dropdown Remove Class From others

I have an overlay Menu that has 3 dropdowns.
When you click on one of the parent items if it has a dropdown , a class is added to the child to "activate" the dropdown and it expands and shows. Currently it works fine , and on click the class is added and removed if clicked again.
The problem is currently you can have all dropdowns active and open at the same time. What I need to happen is to have only one dropdown be able to be active at a time.
if one dropdown is active , and the user clicks on another , the original active dropdown closes and the newly clicked one becomes active.
Also if the dropdown is active and user clicks on the same parent item again the dropdown closes.
Current HTML
I have excluded all other list items except for the ones that have dropdowns.
<ul class="header__overlay-nav">
<li class="js-overlay-dropdown-trigger">
<a class="header__overlay-nav-links" href="#">
After Action Review
<i class="fa fa-angle-down btn__icon-right"></i>
</a>
<ul class="dropdown--overlay">
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Overview
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Review Form
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Performance Card
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Recent Recordings
</a>
</li>
</ul>
</li>
<li class="js-overlay-dropdown-trigger">
<a class="header__overlay-nav-links" href="#">
Downloads
<i class="fa fa-angle-down btn__icon-right"></i>
</a>
<ul class="dropdown--overlay">
<li class="dropdown__item">
<a class="dropdown__links" href="#">
100 Day Challenge App
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Desktop Wallpapers
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Screen Savers
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Forms
</a>
</li>
</ul>
</li>
<li class="js-overlay-dropdown-trigger">
<a class="header__overlay-nav-links" href="#">
Inspiration
<i class="fa fa-angle-down btn__icon-right"></i>
</a>
<ul class="dropdown--overlay">
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Get Your Mojo Working
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links href="#">
Game Changers
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Bold Actions - Big Rewards
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Motivational Videos
</a>
</li>
</ul>
</li>
</ul>
Current Jquery
Here is the original Jquery I was using to do a basic toggle of active class, Basically just using the toggleClass on the child UL of the clicked trigger.
Commented out , I previously tried removing all active classes and then instead of toggling the class on click element I was adding, but removing all classes , only to add it to the clicked one made it not possible to close a dropdown by clicking the same trigger again.
var $overlayDdTrigger = $('.js-overlay-dropdown-trigger');
var $overlayClasses = {
// Active css Class for dropdowns in Main Overlay
OverlayDdActive: 'dropdown--overlay-is-active',
ButtonIconIsRotated: 'btn__icon-is-rotated',
};
$overlayDdTrigger.on('click', function() {
if (_isMobile) {
// Attempt to to remove all active classes on UL's prevents dropdown from
// being able to close if the same trigger is clicked twice
// $('ul.dropdown--overlay-is-active').removeClass($overlayClasses.OverlayDdActive);
$(this).children('ul').toggleClass($overlayClasses.OverlayDdActive);
$(this).find('.btn__icon-right').toggleClass($overlayClasses.ButtonIconIsRotated);
}
});
Thank you for the help in advance, I know there are a lot of questions that relate to this problem on here, I did a lot of searching but could not find any that would help me with this specific case.
i hope this will work plz comment if it cause any problem.
<html>
<body>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
var $overlayDdTrigger = $('.js-overlay-dropdown-trigger');
var $overlayClasses = {
OverlayDdActive: 'dropdown--overlay-is-active',
ButtonIconIsRotated: 'btn__icon-is-rotated',
};
$overlayDdTrigger.on('click', function() {
if($(this).find('ul').hasClass('dropdown--overlay-is-active')){
$overlayDdTrigger.find('ul').removeClass($overlayClasses.OverlayDdActive);
$overlayDdTrigger.find('.btn__icon-right').removeClass($overlayClasses.ButtonIconIsRotated);
}else{
$overlayDdTrigger.find('ul').removeClass($overlayClasses.OverlayDdActive);
$overlayDdTrigger.find('.btn__icon-right').removeClass($overlayClasses.ButtonIconIsRotated);
$(this).find('ul').addClass($overlayClasses.OverlayDdActive);
$(this).find('.btn__icon-right').addClass($overlayClasses.ButtonIconIsRotated);
}
});
</script>
<style>
.dropdown--overlay{
display:none;
}
.dropdown--overlay-is-active{
display: block !important;
}
</style>
<ul class="header__overlay-nav">
<li class="js-overlay-dropdown-trigger">
<a class="header__overlay-nav-links" href="#">
After Action Review
<i class="fa fa-angle-down btn__icon-right"></i>
</a>
<ul class="dropdown--overlay">
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Overview
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Review Form
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Performance Card
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Recent Recordings
</a>
</li>
</ul>
</li>
<li class="js-overlay-dropdown-trigger">
<a class="header__overlay-nav-links" href="#">
Downloads
<i class="fa fa-angle-down btn__icon-right"></i>
</a>
<ul class="dropdown--overlay">
<li class="dropdown__item">
<a class="dropdown__links" href="#">
100 Day Challenge App
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Desktop Wallpapers
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Screen Savers
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Forms
</a>
</li>
</ul>
</li>
<li class="js-overlay-dropdown-trigger">
<a class="header__overlay-nav-links" href="#">
Inspiration
<i class="fa fa-angle-down btn__icon-right"></i>
</a>
<ul class="dropdown--overlay">
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Get Your Mojo Working
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links href="#">
Game Changers
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Bold Actions - Big Rewards
</a>
</li>
<li class="dropdown__item">
<a class="dropdown__links" href="#">
Motivational Videos
</a>
</li>
</ul>
</li>
</ul>
</body>
</html>
Figured Out a solution that works as wanted.
$overlayDdTrigger.on('click', function() {
if (_isMobile) {
// Toggle Class On clicked Element
$(this).children('ul').toggleClass($overlayClasses.OverlayDdActive);
// Remove all Active Dropdowns From all Siblings
$(this).siblings().children('ul').removeClass($overlayClasses.OverlayDdActive);
$(this).find('.btn__icon-right').toggleClass($overlayClasses.ButtonIconIsRotated);
}
});

Bootstrap navbar submenu Active State not working

Bootstrap navbar Active State is not working.
I have bootstrap v3.
I use the class="active" on mynavbar on its submenu when I collapse none work.
Here is my code with js/css/bootstrap files I have included:
<li class="active">
<a href="javascript:;" data-toggle="collapse" data-target="#demoadmin">
<i class="fa fa-fw fa-wrench"></i>Administrator Menu <i class="fa fa-fw fa-caret-down"></i>
</a>
<ul id="demoadmin" class="collapse in">
<li class="active">
Links Editor
</li>
<li>
News Editor
</li>
<li>
Main Category Editor
</li>
<li>
Sub Category Editor
</li>
<li>
Profile Team Editor
</li>
</ul>
</li>
You didn't show us enough HTML to see exactly what you are doing wrong, but it looks like you're trying to get the active class to work on a bootstrap dropdown-menu.
<li class="dropdown active">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-fw fa-wrench"></i>Administrator Menu <i class="fa fa-fw fa-caret-down"></i>
</a>
<ul class="dropdown-menu">
<li class="active">
Links Editor
</li>
<li>
News Editor
</li>
<li>
Main Category Editor
</li>
<li>
Sub Category Editor
</li>
<li>
Profile Team Editor
</li>
</ul>
</li>
DEMO
Try this
$(document).ready(function(){
$(".active").removeClass("active");
$(".dropdown-menu li").addClass("active");
});

Exclude a list item from easytabs.js

I have an unordered list with various tab items:
<nav class="navigation-area">
<ul>
<li>
<a href="#home"><i class="fa fa-home"></i>
Home</a>
</li>
<li>
<i class="fa fa-pencil"></i>Blog
</li>
<li>
<a href="#profile"><i class="fa fa-user"></i>
Profile</a>
</li>
<li>
<a href="#portfolio"><i class=
"fa fa-briefcase"></i> Portfolio</a>
</li>
<li>
<a href="#resume"><i class=
"fa fa-file-text"></i> Resume</a>
</li>
<li>
<a href="#contact"><i class=
"fa fa-envelope"></i> Contact</a>
</li>
</ul>
</nav>
I am trying to get the "Blog" element to link to a site instead of be used as a tab. however the easytabs is breaking the page as it is unable to find the referenced element in the code. How can I skip including this element in the easy tabs? The way I am initializing easytabs is like so:
$('#tab-container').easytabs({
updateHash: false
});
http://jsfiddle.net/6dqc6r4j/1/
the element LI in which is url change in SPAN tag
<span>
<i class="fa fa-pencil"></i>Blog
</span>

Categories