I get this error when I try to run the code below:
Failed: element not visible
Following is the html code for the elements I want to locate:
<a class="dropdown-toggle ng-binding ng-scope" aria-expanded="false"
role="button" href="/" data-toggle="dropdown" ng-if="tab.subtabs">
Content
<span class="caret"></span></a>
<ul class="dropdown-menu ng-scope" role="menu" ng-if="tab.subtabs">
<li class="ng-scope" ng-repeat="test in tab.subtabs">
<a class="ng-binding" target="_self" href="/custom/ui">Custom</a>
</li>
<li class="ng-scope" ng-repeat="test in tab.subtabs">
<a class="ng-binding" target="_self" href="/patch/ui">Patch</a></li>
<li class="ng-scope" ng-repeat="test in tab.subtabs">
<a class="ng-binding" target="_self" href="/swd/ui">Software</a>
I want to click on element within the tags:
<a class="ng-binding" target="_self" href="/custom/ui">Custom</a>
<a class="ng-binding" target="_self" href="/patch/ui">Patch</a>
<a class="ng-binding" target="_self" href="/swd/ui">Software</a>
I have tried following code in protractor, but it is not working:
it("should click on Content and then custom", function(){
element(by.xpath('/html/body/bf-header/div/nav/div/div/div[2]/ul[1]
/li[2]/a')).element(by.xpath('/html/body/bf-header/div/nav/div/div
/div[2]/ul[1]/li[3]/ul/li[1]')).click();
element(by.xpath('/html/body/bf-header/div/nav/div/div/div[2]/ul[1]
/li[2]/a')).element(by.xpath('/html/body/bf-header/div/nav/div/div
/div[2]/ul[1]/li[3]/ul/li[1]')).click();
Well, now you can probably see why the Protractor Style Guide recommends not to ever use XPath location technique:
NEVER use xpath
Why?
It's the slowest and most brittle locator strategy of all
Markup is
very easily subject to change and therefore xpath locators require a
lot of maintenance
xpath expressions are unreadable and very hard to
debug
It is not always true and, if you choose XPath, the expressions you make must at least really be simple and readable. The first thing to fix, if you are gonna stay with XPaths, is not to make absolute XPath expressions - you don't have to start with html element and check every single element going down the tree to the desired element.
In this case, simple "by link text" or "by partial link text" locators should work perfectly:
element(by.linkText("Custom")).click();
Note that the Failed: element not visible error might be thrown, because you don't click the menu to open it up, before trying to click the submenu (assuming these are the submenu links you need to click).
You might also need to wait for the element to be clickable:
var EC = protractor.ExpectedConditions;
var custom = element(by.linkText("Custom"));
browser.wait(Ec.elementToBeClickable(custom), 5000);
custom.click();
Hope that helps.
Related
I have almost done my work and my client ask for keeping submenu opened when user click the item in the menu and also set active color. The idea is better orientation when user actualy is. In React App it wouldn't be problem, cuz whole app works like single page. In this case i've decided use only HTML/JS as my challenge.
Is it even possible somehow keep menu opened/open again menu when new page is loaded please?
I tried make from this app something like single page app by some tutorials like "load paghe without refresh" etc, but nothing worked.
menu
<div class="menu">
<div class="item">
<a class="sub-btn">
Matice
<i class="fas fa-angle-right dropdown"></i>
</a>
<div class="sub-menu">
<a
href="/pages/matice/zakladni-operace.html"
id="matice/zakladni-operace"
onClick="reply_click(this.id)"
class="sub-item">
Základní operace
</a>
<a
href="/pages/matice/hodnosti.html"
id="matice/hodnosti"
onClick="reply_click(this.id)"
class="sub-item">
Hodnost
</a>
<a
href="/pages/matice/determinanty.html"
id="matice/determinanty"
onClick="reply_click(this.id)"
class="sub-item">
Determinanty
</a>
<a
href="/pages/matice/inverzni-matice.html"
id="matice/inverzni-matice"
onClick="reply_click(this.id)"
class="sub-item">
Inverzní matice
</a>
<a
href="/pages/matice/maticove-rovnice.html"
id="matice/maticove-rovnice"
onClick="reply_click(this.id)"
class="sub-item">
Maticové rovnice
</a>
<a
href="/pages/matice/vlastni-cisla-a-vektory.html"
id="matice/vlastni-cisla-a-vektory"
onClick="reply_click(this.id)"
class="sub-item">
Vlastní čísla a vektory
</a>
</div>
</div>
</div>
You can try to get window.location.href on load of your page and add style classes depending on conditionally with something like
<div class="<%= 'yourStyleClass' if #url== 'urURL' %>"> to set active color
You could use AJAX to call the page. But that doesn't sound like what you want. An alternative way in javascript would be to get the current window.location.href when the page loads, then inject a class name into the relevant node, and have the css for that class make it visible and highlighted.
If you're using a library like jQuery this shouldn't be too hard to achieve.
I have a code like this :
<div id="logreg" style="display: none;width:100%;max-width:660px; height:450px;" class="logreg">
my content
</div>
and i need use in many links on my site like this :
<a data-fancybox="logreg" data-src="#logreg" href="javascript:;" class="btnReg float-right">
Register
</a>
<a data-fancybox="logreg" data-src="#logreg" href="javascript:;">
<i class="fas fa-user"></i>
</a>
but doesn't work too many links, only one link work :-(
Please help me.
You are creating gallery that contains two items and both items refer to the same content. Therefore simple use different value for data-fancybox element to not create a group and everything will work fine, demo - https://jsfiddle.net/tecnw6x7/
I have the following code where I use an Anchor tag instead of a button in my Bootstrap dropdown. The problem is that, despite what is said here, when I click on the Anchor tag (labeled Action) the browser opens the Anchor tag instead of just opening the menu. In other words, the default behavior of the Anchor tag is not prevented.
We use Bootstrap v3 and this does not happen in all the environments, only in prod for now and sometimes on my local machines. This happens accross all the known browsers i.e. Chrome, IE, FF for the desktop version, the non-desktop version does not have this functionality, so we did not test it there.
<div class="dropdown btn-group">
<a class="btn dropdown-toggle" role="button" data-toggle="dropdown" href="#">
Action <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>Foo</li>
<li>Bar</li>
</ul>
Finally we used the following line of code to cancel out the default behaviour, but we never figured out the root cause of this happening only in one environment not in others:
$(".btn .dropdown-toggle").click(function(event){ event.preventDefault();})
Why do you need href="#"?
Use href="" instead of href="#".
Try removing from the code
role="button"
why is it an anchor?
you've missed out the data-target attribute as shown in the bootstrap documentation
https://getbootstrap.com/docs/3.3/javascript/#dropdowns
Here's a webpage : http://www.mirakee.com/milind_ek_kavi
Now this webpage contains around 1000's of post by this user, and I wish to like all of them at once.
Each post contains a like button.
Now i want a script(bot type) that would click all the like buttons at once. and all of them get registered(accepted).
Please do tell me where and how to embed the script.
Thanks a lot.
UPDATE:
This is the HTML code for the like button:
<div>
<span class="like_content post_zy2v7yjilw_like">
<a class="like-post" data-remote="true" data-method="post" rel="nofollow noopener" href="/posts/zy2v7yjilw/like">
<span class="heart"></span>
</a>
<a class="likes-count" rel="nofollow noopener" data-remote="true" href="/posts/zy2v7yjilw/likes">
46
</a> </span>
<span class="comment-icon"></span>
<span class="comment-count">1</span>
<span class="reposts-icon"></span>
<a class="comment-count" rel="nofollow noopener" data-remote="true" href="/posts/zy2v7yjilw/reposts">
4
</a> </div>
You can use this
$(".like-post").trigger("click");
The main problem will be that it will trigger click only for elements which are actually available on page. I mean that the posts which are not loaded yet will have no effect of this code.
So, either you can first load all the posts by scrolling manually or you need to write script for that too.
Use jQuery's click() function.
$(element).click();
But may be abusing a feature like that is illegal. I currently don't have access to your DOM on mobile, so you can add your own query instead of element
I use react 0.13.3 with babel 5.8.26. I noticed it started rendering strange markup. This is what I have in js file:
<p className="navbar-text navbar-right dropdown hidden-xs">
<a className="navbar-link dropdown-toggle" href="#" id="accountddl" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"><i className="st st-profile st-2"></i></a>
<ul className="dropdown-menu" aria-labelledby="accountddl">
<li>Action</li>
</ul>
</p>
You can see the output there.
But what it renders back is this:
<p class="navbar-text navbar-right dropdown hidden-xs" data-reactid=".0">
<a class="navbar-link dropdown-toggle" href="#" id="accountddl" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true" data-reactid=".0.0">
<i class="st st-profile st-2" data-reactid=".0.0.0"/>
</a>
</p>
<ul class="dropdown-menu" aria-labelledby="accountddl" data-reactid=".0.1">
<li data-reactid=".0.1.0">
Action
</li>
</ul>
<p/>
As you can see it closes the p tag before rendering ul and in the end it attaches a self-closed p tag.
How to make ul a part of one parent p tag?
Am I doing something wrong?
If I change p to div it works as expected - result
Update
Thanks to the guys comments. I realized that this is not valid HTML. React is good and does its job well. So, when the browser sees the case, it decides to break it the way shown above.
The HTML spec defines rules for how markup may be nested. In this case:
<p> is:
Content categories: Flow content, palpable content.
Permitted content: Phrasing content.
<ul> is:
Content categories: Flow content
Permitted parent elements: any element that accept flowing content
which translates to <ul> elements not being allowed within <p> elements. To avoid this, React and/or the browser will basically pull the <ul> one level up in the DOM and split the <p> around it, resulting in what you are seeing.
Update
From the release notes of the newly released React 0.14:
React DOM now warns you when nesting HTML elements invalidly, which helps you avoid surprising errors during updates.