How to fix exception NoSuchELement in eclipse selenium project? - javascript

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();

Related

Can not read DOM value, getting Vue.js template (in Chromium, both fom DevTools and extension)

I am working on a Chrome extension, which wants to read some values from the page, e.g. item title. But it reads not the actual title but some Vue.js template variable.
Even if I open DevTools, I can't get the value, only the template variable name.
> document.getElementsByClassName("page-title-text")[0]
​
<span class=​"page-title-text">​{{pageTitle}}​</span>​
On the webpage, I can see the actual title. Can I get the raw value somehow? Especially I need the href attribute of a link (tag <a>). I don't really want to use Vue.js in my extension, just get the value from DOM.
Especially I need the href attribute of a link (tag <a>)
You're looking for Element.getAttribute():
console.log(
` a.getAttribute('href') => '${document
.getElementsByClassName("foo")[0]
.getAttribute("href")}'\n`,
`span.getAttribute('class') => '${document
.getElementsByTagName("span")[0]
.getAttribute("class")}'`
);
foo
<span class="page-title-text">bar</span>
Well, the site has tricked me.
> document.getElementsByClassName("page-title-text")[1]
<span class="page-title-text">The Real Title</span>
There is a hidden first element somewhere, which contains the template, that scared me, and also the empty value caused error, so my script has stopped.

Python selenium find element by xpath or css selector

how can i click on the "NATIONAL" text with python selenium
<div class="ellipsis__content">
<ul class="breadcrumb_new" id="breadcrumb">
<li>
<span>NATIONAL</span>
</li>
</ul>
</div>
I tried these below things,
find_element_by_xpath("//div[#id='breadcrumb']/li/span")
find_element_by_css_selector("#breadcrumb > li > span")
Both the methods not working, any idea here
Try this one, should work for you:
ele=driver.find_element_by_xpath("//*[#id='breadcrumb']//span")
ele.click()
May be you need to wait till element is rendered properly.
Code trial 1 :
time.sleep(5)
driver.find_element_by_xpath("//div[#id='breadcrumb']/li/span").click()
Code trial 2 :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#id='breadcrumb']/li/span"))).click()
PS : Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.
Already this question has an answered but adding couple of points.
I tried these below things,
find_element_by_xpath("//div[#id='breadcrumb']/li/span")
The id breadcrumb is part of ul tag but you are referring div tag. It should work if try as below.
find_element_by_xpath("//ul[#id='breadcrumb']/li/span")
find_element_by_css_selector("#breadcrumb > li > span")
There is nothing wrong with CSS locator. It should work still if you are seeing issue you may need to debug and see or try by adding some explicit value.

JavaScript DIV Editing Destroys Functionality of Other Elements

So my website is built using a company's software called Inksoft which leaves me very little to work in the way of customization. So I have to do many workarounds.
Here is my site's homepage.
The header on top of the page only has two links right now. "Products" and "Design Studio". My goal is to add an "About Us" link and "Buyers Guide" to the header as well.
I cannot add new content to the header using Inksoft's backend. So I coded a workaround to replace the content of existing DIV's within the header to say and link to where I want them to go.
The only issue is, the responsive mobile-nav loses functionality when this is implemented. As seen here on this test page.
The test page has the About Us in the top header, added by the use of this code:
<script>
$("#header-nav-designs").html('<document.write="<li id="header-nav-studio"><font color="#000000">About Us</font></li>');
</script>
So, the simplified question is: how do I implement this code without losing the responsive functionality of the nav bar?
The jQuery .html function will replace the HTML inside the target element. If you want to just append the one value, you likely want to .append to the element.
In addition, you aren't setting the HTML to a valid html string. You probably just want to get rid of the <document.write=" at the beginning of the string. The rest of it looks fine with just a cursory glance.
So:
<script>
$("#header-nav-designs").append('<li id="header-nav-studio"><font color="#000000">About Us</font></li>');
</script>
Edit:
After looking at it a little more, it appears as though the $('#header-nav-designs') that you are selecting is already an <li> which means you need to either select the parent <ul> list or you can use the jquery .after function instead.
<script>
$("#header-nav-designs").after('<li id="header-nav-studio"><font color="#000000">About Us</font></li>');
</script>
And as someone else commented above, you are getting an error on the page. It appears as though you are trying to get an element with the id divID and the appending some html to it, but there is no element with the id divID and so you are getting an error saying that you can't read the property innerHTML of null as the call to document.getElementById is returning null (element not found).
Element id header-nav-designs witch your code is referring have CSS style on line 170:
#header-nav-designs {display:none;}
The element will be hidden, and the page will be displayed as if the element is not there. With display:none;
If I understand you correctly your code selector points to wrong element id. It should point $(".header-nav > ul"). Document.write is not needed inside jQuery you need to give only an valid html string as argument.
jQuery html function erase html that is all ready inside element and replace it with html string given as argument. You have to use append if you want to add more html but not remove what is allready in element.
$(".header-nav > ul").append('<li><font color="#000000">About Us</font></li>');
$(".header-nav > ul").append('<li><font color="#000000">Buyers Guide</font></li>');

Python Selenium: Click a href="javascript:()"

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?

What does href expression do?

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();
});

Categories