why does selenium change the element's href? - javascript

I'm using selenium to inspect a web element and then get its "href"
driver.findElement(getSelectorForButton(name)).getAttribute("href")
why the result I get is ...current url...# instead of jut # as I see in the browser console?
<a class="action-btn big-button btn-phone take-button v3" data-model="{"analytics_url":"/coupons/use?action_source=popup&cookie=..uot;],"redirect_url":null}" href="#">
<div class="btn-text">
<span>Call Now</span>
</div>
</a>

I may be wrong but I think it is because
driver.findElement(getSelectorForButton(name));
does not return the DOM element, but a selenium wrapper which getAttribute property (method) invoked with the ('href') argument does not return the href attribute content, but the href property content.
The href property is 'filled' by the browser automatically with the matching prefix for every relative/absolute path in href.
Examples below:
HTML:
Test
Test
Test
JavaScript:
var a = document.getElementById('link1');
console.log(a.href); // '...Whatever_your_url_is...#'
console.log(a.getAttribute('href')); // '#'
var b = document.getElementById('link2');
console.log(b.href); // '...Whatever_your_url_is.../uri'
console.log(b.getAttribute('href')); // '/uri'
var c = document.getElementById('link3');
console.log(c.href); // '...Whatever_your_domain_and_port_is.../uri'
console.log(c.getAttribute('href')); // './uri'
DEMO here: http://jsfiddle.net/j8t470uk/

The reason is (as per docs)
this method will return the value of the given attribute, unless that attribute is not present, in which case the value of the property with the same name is returned (for example for the "value" property of a textarea element). If neither value is set, null is returned.
getAttribute first of all looks for the attribute in the DOM, where if you can see href contains the complete web url.
For example: in the answers you are getting on this question if you inspect the active tab you could see href="/questions/28339297/why-does-selenium-change-the-elements-href?answertab=active#tab-top", but if you have a look at the DOM there you can find this href is appended to http://stackoerflow.com.

Related

Parsing part of a html text using javascript

The output on my page after generating a certain link is:
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
SUCCESS|78502|25cca4bc-08f9-4a59-85f8-64e0d0700924|
</string>
What i'm interested in is the 78502 because it's an unique id i need to use in later protractor tests.
This is the html part of it.
<span xmlns="http://www.w3.org/1999/xhtml" class="text">SUCCESS|78502|25cca4bc-08f9-4a59-85f8-64e0d0700924|</span>
I'm prety blocked atm since i've never done something like this, the first step i took was getting the xpath of the html element and applying the getText method on it and console.log-ing it to check that i can at least get the value but that doesn't seem to give me the value of the element.
Any materials/links that can help me better understand what i need to do is appreciated!
Is that html element unique? If there isn't any other with same xmlns attribute and same class you can get that with pure Javascript:
// Get text inside the element
var text = document.querySelector('span.text[xmlns="http://www.w3.org/1999/xhtml"]').innerText;
// Get an array of the parts ["SUCCESS", "78502" ...]
var text_parts = text.split('|');
console.log(text_parts);
// If that array has a second element (that id) get that second element
var id = '';
if (text_parts.length >= 2) id = text_parts[1];
console.log(id);
If there's a way to generate that html with an id so it's unique it would be more safe, so you are sure the querySelector will pick the right one.
So if you have
<span id="span-with-id" xmlns="http://www.w3.org/1999/xhtml" class="text">SUCCESS|78502|25cca4bc-08f9-4a59-85f8-64e0d0700924|</span>
you could use
var text = document.querySelector('#span-with-id').innerText;
Note that you have to do that with Javascript, after this HTML element is inserted into the document.

Getting value of <a> link?

I am having troubles pulling the value from a link. It's a CSS formatted page and I would really prefer to use a <a> than a <button>.
<button value="1" onclick="showDetails(this.value)">This works</button>
<a value="2" onclick="showDetails(this.value)">This doesn't work</a>
};
xmlhttp.open("GET","getdetails.php?q="+str,true);
xmlhttp.send();
How can I get the value of <a> when it is clicked and not having it go somewhere?
Only a select few elements, like <input>s, <textarea>s, and <button>s can have value properties:
console.log(
document.querySelector('a').value
);
<a value="val">a</a>
If you have to use the value attribute, use the getAttribute method instead of dot notation:
console.log(
document.querySelector('a').getAttribute('value')
);
<a value="val">a</a>
Another option would be to use data attributes instead, which would be more appropriate than value="s when working with an <a>:
console.log(
document.querySelector('a').dataset.value
);
<a data-value="val">a</a>
(also make sure to attach your event handlers properly using Javascript if at all possible - inline handlers are generally considered to be pretty poor practice - try using addEventListener)
To use addEventListener, select your a, and call addEventListener on it. For example, if your <a> has an id of details:
const details = document.querySelector('#details');
details.addEventListener('click', () => {
showDetails(details.dataset.value);
});
function showDetails(str) {
console.log('showing details for ' + str);
}
<a id="details" data-value="thevalue">click for details</a>
You can write a Javascript function to get the value from the link as follows:
function showDetails(a){
let value = a.getAttribute("value");
// view value
console.log(value)
}
<!--<button value="1" onclick="showDetails(this)">Button link</button>-->
<a value="2" onclick="showDetails(this)">Anchor link</a>
Your issues has 2 parts:
#1: Use of correct attribute
You should not use the value attribute in <a> tag, as it's not a valid attribute for HTML standard; try to use data-val instead. Attributes starting with data- allow us to store extra information on standard, semantic HTML elements without other hacks.
Example:
<a data-val="2" onclick="showDetails(this)">Test</a>
For the JS function, it can be written as:
function showDetails(obj) {
console.log(obj.dataset.val); // 2
}
References: https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
#2: Prevent the <a> gets redirected
The initial choice of using <a> is incorrect, as <a> is designed to: (1) redirect to other page via hyperlink specified; or (2) go to certain section in the page using anchor name.
However, you can still stop the redirection using JavaScript (though not suggested). Edit your onclick function as below:
<a data-val="2" onclick="showDetails(this); return false;">Test</a>
Note the return false is added.
p.s. for better coding standard, you should separate JS from HTML structure.
Anchor tag does not have a value attribute, you can read about it in mdn. If you need to assign a value to an anchor tag you can use custom data attribute data-*. In order to get values from data-* in your javascript function can try something like this
const anchor = document.querySelector('a');
const str = anchor.data.value;
And then use it in your ajax logic.
const url = 'getdetails.php';
const params = `q=${str}`;
const http = new XMLHttpRequest();
http.open('GET', `${url}?${params}`, true);
// ... other logic

How does this href javascript logic work?

I made a mistake and forgot to use the attribute value in some code I was writing:
var link = document.getElementsByClassName("summary-title-link")[0],
ele = document.createElement("a");
ele.href = link;
and I was surprised to see that it still worked regardless.
In extension with this example below, I find it odd that I don't need to target the href attribute before using pathname? it seems to assume somehow that I want the pathname from the href attribute.
var link = document.getElementsByClassName("summary-title-link")[0].pathname;
"/test-link/1"
When you convert an anchor element to a string, you actually get the href value, or more precisely "the whole URL", and not the outerHTML as you would with most other elements, that's why it works
var href = document.getElementsByClassName("test")[0]; // DOM element
console.log(href.toString()); // gives you "http://google.com"
<a class="test" href="http://google.com">link</a>
This special behaviour for anchors is specified in the specification
HTMLHyperlinkElementUtils.toString()
Returns a USVString containing the whole URL.
It is a synonym for URLUtils.href, though it can't be used to modify the value.

Grab relative URL with elementIdAttribute in Nightwatch

I want to grab the 'href' attribute from a link exactly as is in the source code so that I can locate the same link on another page. I thought that elementIdAttribute would grab the attribute and allow me to use it in a CSS locator, but for some reason elementIdAttribute completes relative URLs and appends slashes to the ends of some.
Here is the code I'm using to grab the 'href' attribute from the links on a page:
browser.elements("css selector", "div.field-item.even a", function(link_array) {
link_tot = link_array.value.length;
//Fetch the url from each 'a' tag in the content
for (var x = 0; x < link_tot; x++){
browser.elementIdAttribute(link_array.value[x].ELEMENT, "href", function(links) {
console.log(links.value);
urls.push(links.value);
});
}
})
If the 'href' property is href='node/16376', then the link my program ends up outputting is https://www.website.com/node/16376. I want it so that it only outputs "node/16376" without the full url being appended to it.
Is there any way to grab the 'href' attribute exactly as is (ie. relative URLs without extra slashes appended to them) so that it can be used in a CSS selector to find the same link on another page?
Why not just modify your result by using JavaScript String replace() Method :
urls.push(links.value.replace('https://www.website.com/',''));

Javascript: replace a string in element.src attribute

Hi I am currently trying to replace a query string value in a a link's src attribute.
it works fine in firefox but not in ie.
example:
<a id="link" href="#" src="http://somedomain.com?id=123&size=20">link</a>
then on my js it looks kinda like this:
var link = document.getElementById('link');
link.src.replace('size=20', 'size=45');
in ie, it returns something like src is not an object error;
anyone kind enough to lend a hand?
also, i need this to be on native javascript so please don't suggest a framework as a solution thanks.
To get it to work in IE you're going to need to use link.setAttribute('src', ...).
use:
var link = document.getElementById('link');
var src = link.getAttribute("src").replace('size=20', 'size=45');
link.setAttribute("src", src);
Well, links (anchor elements) don't have a src attribute, I think that you want to change the href attribute:
var link = document.getElementById('link');
link.href = link.href.replace('size=20', 'size=45');
In your case the "src" attribute in your link is an expando attribute, since an anchor tag does not have a src.
When working with expando attributes, it's safest to set and get the values using the setAttribute('attributeName',***value*)** and getAttribute('attributeName') accessors.
To find out more about getAttribute and setAttribute you can check here:
https://developer.mozilla.org/en/DOM/element.getAttribute
https://developer.mozilla.org/en/DOM/element.setAttribute
To find out more about DHTML properties you can check the MSDN Resource here:
http://msdn.microsoft.com/en-us/library/ms533055%28VS.85%29.aspx
Example Code using getAttribute and setAttribute:
var link = document.getElementById('link');
var src = link.getAttribute('src');
link.setAttribute('src',src.replace('size=20','size=40'));
I believe getAttribute is more cross-browser friendly.
var link = document.getElementById('link');
var result = link.getAttribute("src").replace('size=20', 'size=45');
Also, the replace function returns a string. It doesn't operate on the string it is called against. This means you have to assign the result.
link.setAttribute("src", result);

Categories

Resources