Selenium - Unable to find the hidden element - javascript

I am trying to create an framework where I want to find whether an webelement is hidden or not before performing an action on the web element.
I have a password field which is hidden and is structured as below
<div class=hidepassword>
<input password field >
<div>
When I query the input tag with the following lines
Isvisible1 = (string)js1.ExecuteScript("return (window.getComputedStyle?window.getComputedStyle(arguments[0], null):arguments[0].currentStyle).visibility;", myCurElement);
Isvisible2 = (string)js1.ExecuteScript("return (window.getComputedStyle(arguments[0], null).getPropertyValue('display'));", myCurElement);
Isvisible3 = (bool)js1.ExecuteScript("return !(arguments[0].offsetHeight <= 1);", myCurElement);
I am getting all the values indicating it as visible.
Later , got to know that the class which the preceding div has is making the input invisible.
I tried to get the value of overflow which is made available in the .css file for the class hidepassword
But unfortunately, there are lot of css values for the class hidepassword and when I use the below javascript function, I am able to get only one of its CSS value
public string getStyle(string ClassName)
{
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
return (String)js.ExecuteScript(
"function getStyle(ClassName) {" +
"var styleSheets = window.document.styleSheets;" +
"var styleSheetsLength = styleSheets.length;" +
"for (var i = 0; i < styleSheetsLength; i++)" +
"{" +
" var classes = styleSheets[i].rules || styleSheets[i].cssRules;" +
" if (!classes)" +
" continue;" +
" var classesLength = classes.length;" +
" for (var x = 0; x < classesLength; x++)" +
" {" +
" if (classes[x].selectorText == ClassName)" +
" {" +
" var ret;" +
" if (classes[x].cssText)" +
" {" +
" ret = classes[x].cssText;" +
" }" +
" else" +
" {" +
" ret = classes[x].style.cssText;" +
" }" +
" if (ret.indexOf(classes[x].selectorText) == -1)" +
" {" +
" ret = classes[x].selectorText + ret ;" +
" }" +
" return ret;" +
" }" +
" }" +
"}" +
"}return getStyle(arguments[0]);", ClassName);
}
Is there a way to get all the css values for the particular class name and then based on the css values for the class, we can make a call whether the element is visible or not visible. ?
Thanks in advance for all your help on this.

Selenium had supply api:isDisplayed() to detect element visibility, why you want to implement it as such complex by yourself

Related

Vanilla JS addEventListener change on select fires only once

I am using an ecommerce system where I dont have access to HTML code or anything but I can add custom JS code to alter some things and CSS.
I need to edit the shipping info text which is right to Doba dodania text.
My issue is that the event fires only once and not on every select change event.
Can someone help me why it is firing only once? It was needed to add SetTimeOut too.
Please check the page and console logs here:
https://www.privlacuj.sk/Hacik-Offset-Light-Class-AT-21-cena-za-1ks-d2336_1013278452.htm
My code is:
<script type="text/javascript">
function change_doba_dodania() {
var c757_counter = document.querySelectorAll(".c757").length;
var variant = document.querySelectorAll(".c755.variant").length;
var out_of_stock = document.querySelectorAll(".c757.out-of-stock").length;
console.log(c757_counter);
console.log(variant);
console.log(out_of_stock);
if (out_of_stock > 0) {
console.log("Nincs raktaron");
}
if ( ( c757_counter >= 2 ) && ( out_of_stock == 0 ) ){
var dd_text = document.getElementsByClassName("c757")[1].innerHTML;
console.log(dd_text);
var dd_text_array = dd_text.split(" ");
var dd_final = dd_text_array.filter(String);
console.log(dd_final);
if (dd_final[2] == "zajtra") {
document.getElementsByClassName("c757")[1].innerHTML = dd_final[6] + " " + dd_final[7] + " " + dd_final[8] + " " + dd_final[9] + " " + dd_final[10] + " a Vaša zásielka bude expedovaná už " + dd_final[2];
} else {
document.getElementsByClassName("c757")[1].innerHTML = dd_final[6] + " " + dd_final[7] + " " + dd_final[8] + " - " + dd_final[9] + " a Vaša zásielka bude expedovaná už " + dd_final[2];
}
}
}
window.addEventListener('DOMContentLoaded', (event) => {
change_doba_dodania();
});
var variant = document.querySelectorAll(".c755.variant").length;
if (variant > 0){
document.querySelector('.c757 select').addEventListener('change', function()
{setTimeout(change_doba_dodania, 1500)});
document.querySelector('.c757 select').addEventListener('change',() =>
setTimeout(console.log, 1000, "Changed")
)
}
If i got your question, your problem is querySelector.
querySelector only selects the first element with the given class name. If you want to select all the elements with the given class name, you should use querySelectorAll.
document.querySelectorAll(".c757 select").forEach(select => {
select.addEventListener(...)
})

How to split innherHTML string using Javascript into specific parts after a certain character like a '+' sign

I need to break a string apart after certain characters.
document.getElementById("result").innerHTML = Monster + "<p id='vault" + loop + "'> || HP: " + HP + "</p>" + " || Defense: " + Def + " || Attack: " + ATK + " || Can it Dodge/Block: " + DB + " || Can it retaliate: " + RET + " || Initative: " + INT + " || Exp: " + MEXP + " <input type='submit' class='new' onclick='Combat(" + loop + ")' value='FIGHT!'></input>" + "<br><br>" + A;
function Chest(id){
window.open('LootGen.html', '_blank');
}
function Combat(id){
document.getElementById("C").value = document.getElementById("vault" + id).innerHTML;
}
When this runs the value that results is:
|+HP:+20
However I only want '20' part,now keep in mind that this variable does change and so I need to use substrings to somehow pull that second number after the +. I've seen this done with:
var parameters = location.search.substring(1).split("&");
This doesn't work here for some reason as first of all the var is an innher html.
Could someone please point me in the write direction as I'm not very good at reading docs.
var text = "|+HP:+20";
// Break string into an array of strings and grab last element
var results = text.split('+').pop();
References:
split()
pop()
using a combination of substring and lastIndexOf will allow you to get the substring from the last spot of the occurrence of the "+".
Note the + 1 moves the index to exclude the "+" character. To include it you would need to remove the + 1
function Combat(id){
var vaultInner = document.getElementById("vault" + id).innerHTML;
document.getElementById("C").value = vaultInner.substring(vaultInner.lastIndexOf("+") + 1);
}
the code example using the split would give you an array of stuff separated by the plus
function Combat(id){
//splits into an array
var vaultInner = document.getElementById("vault" + id).innerHTML.split("+");
//returns last element
document.getElementById("C").value = vaultInner[vaultInner.length -1];
}

How do I copy (or even having a button to select it all) a document.getelementbyid output field in html?

I'm trying to essentially set up a button that will either copy a bunch of text that will get output to a document.getelementbyid output to help me out while at work. This is what I have so far for the output and everything works, but would love to have a button that will automatically highlight everything taken from all my input fields.
function display(){
var caller = document.getElementById("form1").value;
var ctn = document.getElementById("form2").value;
var fan = document.getElementById("form3").value;
var business = document.getElementById("form4").value;
var requestor = document.getElementById("form5").value;
var reason = document.getElementById("form6").value;
document.getElementById("output").innerHTML = "form1: " + form1 + "<br>form2: " + form2 + "<br>form3: " + form3 + "<br>form4: " + form4 + "<br>form5: " + form5 + "<br>form6: " + form6;
}
This feeds data from my input fields at the top (naturally they have different names and labels in the document, just can't copy anything proprietary here). The below codes are the button code and the paragraph code to display it when I click so that it appears on the page for me to select.
<button onclick="display();" style="width: 50px; background-color:#3ea055">Submit</button>
<p id="output"></p>
I've tried several different snippets of code online to get it to either select or copy or whatever, and it isn't working.
you dont have variables named form1 form2 etc., in the output area I've changed the values to your variable names try this
function display(){
var caller = document.getElementById("form1").value;
var ctn = document.getElementById("form2").value;
var fan = document.getElementById("form3").value;
var business = document.getElementById("form4").value;
var requestor = document.getElementById("form5").value;
var reason = document.getElementById("form6").value;
document.getElementById("output").innerHTML = "form1: " + caller + "<br>form2: " + ctn + "<br>form3: " + fan + "<br>form4: " + form4 + "<br>form5: " + requestor + "<br>form6: " + form6;
}
In the line where you print the values to the output element you need to use the variables you just filled.
document.getElementById("output").innerHTML = "form1: " + caller + "<br>form2: " + ctn+ "<br>form3: " + fan + "<br>form4: " + business + "<br>form5: " + requestor + "<br>form6: " + reason;

dynamics crm 4.0 lookup field onload() query

I have an account entity with a lookup field schoolLookupId which refers back to a custom entity new_schools. The lookup field only display the name of the school. What I would like to be able to do using the onload() event handler of the account form is to run some javascript code that will query the new_phonenumber attribute of the new_schools entity to see if it matches a value i provide lets say var x = "1234" and if it does then update schoolLookupId accordingly with the name of the school that corresponds with the found phone number. i.e update the lookup field with a phone number that already exists without creating a completely new lookup value.
I can get the attributes of the lookupfield using
var name = crmForm.all.schoolLookupid.DataValue[0].name
var id = crmForm.all.schoolLookupid.DataValue[0].id
var typename = crmForm.all.schoolLookupid.DataValue[0].typename
but I can't figure out how to retrieve, compare the data that lies behind the lookup field, and update the lookupfield accordingly.
Your help as always is invaluable.
Try put this code in load event:
var xml = "" +
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
GenerateAuthenticationHeader() +
" <soap:Body>" +
" <RetrieveMultiple xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" +
" <query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryExpression\">" +
" <q1:EntityName>new_schools</q1:EntityName>" +
" <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
" <q1:Attributes>" +
" <q1:Attribute>new_schoolsid</q1:Attribute>" +
" </q1:Attributes>" +
" </q1:ColumnSet>" +
" <q1:Distinct>false</q1:Distinct>" +
" <q1:Criteria>" +
" <q1:FilterOperator>And</q1:FilterOperator>" +
" <q1:Conditions>" +
" <q1:Condition>" +
" <q1:AttributeName>new_phonenumber</q1:AttributeName>" +
" <q1:Operator>Equal</q1:Operator>" +
" <q1:Values>" +
" <q1:Value xsi:type=\"xsd:string\">"+crmForm.all.new_phonenumber.DataValue+"</q1:Value>" +
" </q1:Values>" +
" </q1:Condition>" +
" </q1:Conditions>" +
" </q1:Criteria>" +
" </query>" +
" </RetrieveMultiple>" +
" </soap:Body>" +
"</soap:Envelope>" +
"";
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "http://"+window.location.hostname+":"+window.location.port+"/mscrmservices/2007/crmservice.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction"," http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
xmlHttpRequest.send(xml);
var resultXml = xmlHttpRequest.responseXML;
if (_resultXml.xml.search('<q1:new_schoolsid')>0)
{
var val = xmlDoc.getElementsByTagName("q1:new_schoolsid")[0].childNodes[0].nodeValue;
var lookupitem = new Array();
lookupitem[0] = new LookupControlItem(val , typecode, name);
crmForm.all.schoolLookupid.DataValue = lookupitem ;
}
}
I don't try this code be careful. Use this code as a guide.
Hope this helps.
If i answered your question, please mark the response as an answer and also vote as helpful.

google calendar api - getting undefined for output for gd$where

i'm able to parse in and display data for all pieces of my code except in this line
" where: " + e.gd$where.valueString + // < this line is displaying undefined
here is the code block that is doing the processing. everything else displays correct data
Titanium.API.info(cal.feed.entry.length);
var i;
for (i=0; i < cal.feed.entry.length; i++){
var e = cal.feed.entry[i];
Titanium.API.info("title: " + e.title.$t +
" content " + e.content.$t +
" when: " + e.gd$when[0].startTime + " - " + e.gd$when[0].endTime +
" evenstatus" + e.gd$eventStatus.value +
" where: " + e.gd$where.valueString + // < this line is displaying undefined
" gcal$uid: " + e.gCal$uid.value
);
here is what should be displayed from the calendar
"gd$where": [{
"valueString": "Any of the 11 elementary schools"
}],
gd$where is an array of objects. In order to access "valueString" in the first key, you need to access it from within that object, like so:
gd$where[0].valueString

Categories