I am using chromedriver and I have the following webpage source:
<form id="stepLinksForm" name="stepLinksForm" method="POST" target="mainFrame">
<ul>
<li> Action One </li>
<li> Action Two </li>
<li> Action Three </li>
</ul>
</form>
After clicking anyone of the href, the browser goes to a new page but the url stays the same.
What I want to achieve is clicking the first href, i.e.
<li> Action One </li>
I have tried find_element_by_xpath, link_text and some other methods suggested on the Internet but none of them works.
I really appreciate if someone could help.
Instead of click you can call the javascript code directly:
browser.execute_script("submitLink('action_one.htm')")
which equivalent to javascript:submitLink('action_one.htm')
Or you can find the a by its text:
browser.find_elements_by_xpath("//a[contains(text(), 'Action One')]")
To click on the first href with text as Action One you can use either of the following options (Python Language Binding Art) :
linkText :
driver.find_element_by_link_text("Action One").click()
cssSelector :
driver.find_element_by_css_selector("a[href*='action_one.htm']").click()
xpath :
driver.find_element_by_xpath("//a[contains(#href,'action_one.htm') and contains(.,'Action One')]").click()
Update
As you are unable to locate the element through LINK_TEXT, CSS, XPATH and even after time.sleep() it is pretty much confirmed that the element is within an frame which is denoted by the <frame> tag.
Now as you are able to see them by "Inspect", locate the element within the HTML DOM and traverse up the HTML. At some point you will find a <frame> tag. Grab the attributes of the <frame> tag and switch to the intended frame first and then try to use the Locator Strategies provided in my answer. Here you can find a detailed discussion on How can I select a html element no matter what frame it is in in selenium?
Related
I'm learning about JavaScript from an udemy tutorial and I try to make API calls. There is a website about recipes and I make API calls. And I have a misunderstanding because until now I knew that an href is a link, not a number.
This is a piece of code from index.html and the href is an id:
<li>
<a class="results__link results__link--active" href="#23456">
<figure class="results__fig">
<img src="img/test-1.jpg" alt="Test">
</figure>
<div class="results__data">
<h4 class="results__name">Pasta with Tomato ...</h4>
<p class="results__author">The Pioneer Woman</p>
</div>
</a>
</li>
And this is a recipe list that I receive if I make an API call and I need to put the recipe_id which is a number in the href. And I don't understand how can I put a number in the href
Yes. If the href is a # flowed by an element id it is what is called an anchor link. It will get you to the element with the given id in the same page. You can read more about it here.
You can use a number as a hyperlink, in this case anyway.
The # means it is referring to an element with that id on the page. To my knowledge it is only classes that you cannot use a number at the beginning without escaping it.
You are also able to leave the current page and go to an element on a different page. You can do this by tailing your #id on to the url string you are used to seeing.
If you give more background into the project we might be able to give less vague answers.
Can a href be an ID?
In short, Yes.
href doesn't necessarily always mean an external link, it could link to an element on the current html page, which from the example you have provided i think this is the case.
If you map your recipe_id as a id to an element in your page, and you then say reference the recipe_id as a href when you click your href the page should scroll / navigate to the element with that id.
EXception occur (element not found # given xpath ) when try find element by x path in eclipse project using ie driver in maven project , this element is inside iframe,
when inspect desired element, I found it in the following structure:
<div id="idName">
<div class="container">
<div>
<p class="v1">..............notice this repeated for many different href
<a href=
<span class="v2".........notice this repeated for many different href
<b>part of label</b>
rest of label
<br></br>
When I used
webelement.findElement(By.xpath("//*[#id='idName']/div/div/p/a")).getAttribute("href"))
this results in exception when run No Such Element Exception
, seems I miss something in the relative XPath, any ideas ?
Note: i tried to switch driver to iframe before find element but it didn't help and still having exception .
Thanks A lot for any help .
Based on the HTML provided above best bet would be to go for first anchor tag following the div 'ID' assuming that ID is unique throughout the page you are working on.
Modify the locator as below and give it a try:
//*[#id='idName']//following::a
If this returns more than 1 link in your page then you can add an index at the end as below:
(//*[#id='idName']//following::a)[1]
when the element we want to get it`s attribute exist inside iframe then we shall switch to this frame first :
driver.switchTo().frame("frameid").findElement(By.xpath("element xpath")).getAttribute("href");
then switch to default content to go out of frame:
driver.switchTo().defaultContent();
I am using class names on my <a> elements so that I categorize them for our analytics(e.g. "form", "favorite", "carousel link", etc). The class name used does not have any css styling associated with it; the purpose is strictly to aid the analytics in categorizing the link. This is done by having some js that runs when the page loads and attaches an onclick function to all links. This function gets the text of the link and the link's class. An ajax http get is sent to our internal Analtyics application with the text of the link clicked and the name of the link class (as the category).
My questions regarding this are:
1) Since a given <a> (or any html element for that matter) can have one or more classes, is there a way to know where one class name ends and another begins? In my experience, I've seen the class names separated by only spaces so is parsing this even possible if one of the classes is a multi-word value separated by spaces?
2) I have a feeling this could be handled in a better manner. Any thoughts on this?
I'd go with a custom data tag for this:
data-analytics="form"
etc
That way you can be sure it is not going to conflict with any of your css / js hooks as you have effectively created a unique name space for your analytics references.
To expand on the answer by #SimonMason, who pointed out that using a data-* attribute gives you much clearer control over what to do with your analytics links. I notice you tagged this jQuery, which makes this easier still
See the snippet below
$(document).on('click','[data-analytics]',function(){
var analytics = $(this).data('analytics');
alert('You clicked a link tagged: ' + analytics);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a data-analytics="form" href="#">A form link</a> <br>
<a data-analytics="form" href="#">Another form link</a> <br>
<a data-analytics="carousel" href="#">A carousel link</a> <br>
I made a navigation bar as tabs in my website, and I used the onlink identity to specify the current tab with certain characteristics. My problem is that when I change tabs, I don't know how to make the previous tab id set as none and the current one set as onlink.
Here's the navigation bar code:
<div id="indNavBar">
<div id="indHolder">
<ul>
<li><a onclick="DisplayDIV('IndPage');HideDIV('DoubleInd')" id="onlink">Single Indicator</a></li>
<li><a onclick="DisplayDIV('DoubleInd');HideDIV('IndPage');">Double Indicators</a></li>
</ul>
</div>
</div>
There's a simple ways but it's somehow stupid, which is to make each current tab as a whole page and when I click another tab, it's just given the url of clicked tab which goes to the page with specified onlink id, but this requires reloading the whole page that's why I'm seeking a better solution.
You can get the control being clicked by passing this in javascript method
onclick="DisplayDIV('IndPage', this);
function DisplayDIV(IndPage, sourceObj)
{
alert(sourceObj.id);
}
Are you ok do use the jQuery Library?
If so you can avoid putting inline javascript into your html and use toggleClass http://api.jquery.com/toggleClass/
You are trying to use HTML ids in the wrong way.
Ids are unique identifiers for HTML tags. They should not change at runtime.
Instead, apply CSS classes to the tab you want to be visible.
CSS
.hide {display:none;}
Javascript
var indpage = document.getElementById("IndPage");
if (!indpage.classList.contains("hide")) {
indpage.classList.add("hide");
}
Then your HTML at runtime will change to
<div id="IndPage" class="hide">...</div>
This is the standard approach.
And you can do much more with this idea.
I agree that making a tab a whole page is not a good idea. You can use javascript to apply CSS classes to hide and remove that class to show again.
Its also a good idea to learn how to separate your javascript from your HTML. Please read some more tutorials on this. One for instance: Unobtrusive Javascript
Here is a jquery way to do it: http://jsfiddle.net/surendraVsingh/HyAhL/
$('#indHolder a').click(function(){
$(this).attr('id', 'onlink');
$(this).parent().siblings().find('a').removeAttr('id');
});
I took hints from the answers above and it worked as the following:
function putOnlink(x){
document.getElementById('onlink').id = "none";
$(x).attr('id','onlink');
}
and the tabs code is:
<div id="indNavBar">
<div id="indHolder">
<ul>
<li><a onclick="DisplayDIV('IndPage');HideDIV('DoubleInd');putOnlink(this);" id="onlink">Single Indicator</a></li>
<li><a onclick="DisplayDIV('DoubleInd');HideDIV('IndPage');putOnlink(this);document.getElementById('onlink').id='none'">Double Indicators</a></li>
</ul>
</div>
</div>
I just wanna not that in the second link I had to change the id of the first link twice because it didn't work once, maybe cause its id is set in the tag not just when clicked.
I have seen the following href used in webpages from time to time. However, I don't understand what this is trying to do or the technique. Can someone elaborate please?
An <a> element is invalid HTML unless it has either an href or name attribute.
If you want it to render correctly as a link (ie underlined, hand pointer, etc), then it will only do so if it has a href attribute.
Code like this is therefore sometimes used as a way of making a link, but without having to provide an actual URL in the href attribute. The developer obviously wanted the link itself not to do anything, and this was the easiest way he knew.
He probably has some javascript event code elsewhere which is triggered when the link is clicked, and that will be what he wants to actually happen, but he wants it to look like a normal <a> tag link.
Some developers use href='#' for the same purpose, but this causes the browser to jump to the top of the page, which may not be wanted. And he couldn't simply leave the href blank, because href='' is a link back to the current page (ie it causes a page refresh).
There are ways around these things. Using an empty bit of Javascript code in the href is one of them, and although it isn't the best solution, it does work.
basically instead of using the link to move pages (or anchors), using this method launches a javascript function(s)
<script>
function doSomething() {
alert("hello")
}
</script>
click me
clicking the link will fire the alert.
There are several mechanisms to avoid a link to reach its destination. The one from the question is not much intuitive.
A cleaner option is to use href="#no" where #no is a non-defined anchor in the document.
You can use a more semantic name such as #disable, or #action to increase readability.
Benefits of the approach:
Avoids the "moving to the top" effect of the empty href="#"
Avoids the use of javascript
Drawbacks:
You must be sure the anchor name is not used in the document.
The URL changes to include the (non-existing) anchor as fragment and a new browser history entry is created. This means that clicking the "back" button after clicking the link won't behave as expected.
Since the <a> element is not acting as a link, the best option in these cases is not using an <a> element but a <div> and provide the desired link-like style.
is just shorthand for:
It's used to write js codes inside of href instead of event listeners like onclick and avoiding # links in href to make a tags valid for HTML.
Interesting fact
I had a research on how to use javascript: inside of href attribute and got the result that I can write multiple lines in it!
<a href="
javascript:
a = 4;
console.log(a++);
a += 2;
console.log(a++);
if(a < 6){
console.log('a is lower than 6');
}
else
console.log('a is greater than 6');
function log(s){
console.log(s);
}
log('function implementation working too');
">Click here</a>
Tested in chrome Version 68.0.3440.106 (Official Build) (64-bit)
Tested in Firefox Quantum 61.0.1 (64-bit)
It is a way of making a link do absolutely nothing when clicked (unless Javascript events are bound to it).
It is a way of running Javascript instead of following a link:
link
When there isn't actually javascript to run (like your example) it does nothing.
Refer to this:
Link to the website opened in different tab
Link to the div in the page(look at the chaneged url)
Nothing happens if there is no javaScript to render
javascript: tells the browser going to write javascript code
Old thread but thought I'd just add that the reason developers use this construct is not to create a dead link, but because javascript URLs for some reason do not pass references to the active html element correctly.
e.g. handler_function(this.id) works as onClick but not as a javascript URL.
Thus it's a choice between writing pedantically standards-compliant code that involves you in having to manually adjust the call for each hyperlink, or slightly non-standard code which can be written once and used everywhere.
Since it is a styling issue, instead of polluting the HTML with non valid syntax, you could/should use a W3 valid workaround:
Format the HTML properly, without href, following the W3 accessibility guide lines for buttons.
Use CSS to fix the initial goal of applying a clickable UX effect on a control.
Here's a live example for you to try the UX.
HTML
<a role="button" aria-pressed="false">Underlined + Pointer</a>
<a role="button" aria-pressed="false" class="btn">Pointer</a>
CSS
a[role="button"]:not([href]):not(.btn) { text-decoration: underline; }
a[role="button"]:not([href]) { cursor: pointer; }
I was searching for a solution that does not refresh pages but opens menu items on Ipads and phones.
I tried it on also mobile, It works well
Dr
1. Use that java script to Clear an HTML row Or Delete a row using the id set to a span and use JQuery to set a function to that span's click event.
2. Dynamically set the div html to a string variable and replace {id} with a 1 or 2 etc. cell of a larger div table and rows
<div class="table-cell">
<span id="clearRow{id}">
Clear
</span>
</div>
<div class="table-cell">
<span id="deleteRow{id}">
Delete
</span>
</div>
//JQuery - Clear row
$("#clearRow" + idNum).click(function(){
$("someIDOrWildcardSelector" + idNum).val("");
$("someIDOrWildcardSelector" + idNum).val("");
$("someIDOrWildcardSelector" + idNum).val("");
});
//JQuery to remove / delete an html row
$("#deleteRow" + idNum).click(function(){
//depending upon levels of parent / child use 1 to many .parent().parent().parent()
$(this).parent().remove();
});