How to access the "hidden" style attrabute using javascript and protractor - javascript

I have a webpage with a search. If the search is invalid using data such as special characters then a warning message appears.
When the page loads the CSS loads as follows:
<div class="searchError" id="isearchError" style="display: none;">
When you input invalid text and press search the above changes to
display: block; opacity: …;
and that also brings up a <div class="marker"></div> with an error message.
I have tried the following var styleValue = element(by.id('ideliveryareaerror')).getCssValue('style'); but I get a tree structure of the element.
Example of my code:
var styleValue = element(by.id('isearchError')).getCssValue('style');
browser.actions().sendKeys(protractor.Key.ENTER).perform();
browser.sleep(1000);
console.log(styleValue);
browser.sleep(1000);
What I want to do is:
Get the style attributes value (Should be none)
Press enter with invalid data
Get the style attributes value (Should be block)
Get error message text
Image of my code:

You're using getCssValue('style'), but you want getCssValue('display'). getCssValue gets the CSS value, not an HTML attribute. (I don't use protractor, but the method name and what you were asking for jumped out at me. :-) )
So something like:
var searchError = element(by.id('isearchError'));
expect(searchError.getCssValue('display')).toBe('none');
browser.actions().sendKeys(protractor.Key.ENTER).perform();
browser.sleep(1000);
expect(searchError.getCssValue('display')).toBe(''); // Or possibly 'block' or one of the others
console.log(styleValue);
browser.sleep(1000);

Have you tried with the isDisplayed method protractor gives you?
If you expect the element to be displayed/not displayed you could go like this:
expect(element(by.id('ideliveryareaerror')).isDisplayed()).toBe(true); // (or false)
Additionally, you are getting the tree structure of the element because getCssValue is a promise that needs to be resolved, that's why it might not work with plain console.log
In that case, you'd need to go like this:
var styleValue = element(by.id('isearchError')).getCssValue('style')
.then( function(style) {
console.log(style);
});

Related

Reset before adding element and class

I've been trying to reset after inserting an element with a class with no success. Tried also innerHTML="" but it is not working.
Maybe because I'm using insertAdjacentHTML(). - ? I couldn't find a remove method before inserting.
let small = document.querySelector("small")
let img_1 = document.querySelector('[name="img_1"]')
//Image fields validation
if (img_1.value =="") {
img_1.classList.add('is-invalid_create')
small = '<small class="text-danger__Create">Campo imagen 1 no puede estar vacío</small>'
img_1.insertAdjacentHTML("afterend", small);
} else {
img_1.classList.add('is-valid_create')
img_1.classList.remove('is-invalid_create')
}
I'm trying to build a validation with an error message if fields are . I used insertAdjacentHTML because innerHTML was not showing the text.
fiddle : https://jsfiddle.net/gzsudqvm/
I tried to do a simpler approach like:
function setErrorFor(input, message) {
input.innerHTML = ""
input.classList.add('is-invalid_create')
input.innerHTML = "<small class='danger'>"+message+"</small>"
}
But the message is not rendering, and there are no errors.
It's hard to tell without seeing more of your code - without understanding just how/what you are trying to reset.
tried also innerHTML=""
For which element? If it was something like img_1.innerHTML="", then your small gets left behind because you added it outside img_1 . (If that's intentional/necessary then you could try something like el.parentElement.removeChild(el) to remove the left-over elements separately.)
used insertAdjacentHTML because innerHTML was not showing the text
Does the debugger show any errors? When you inspect the outer element, has it not been added to html at all, or is the text just not rendering?
EDIT: now that I can see the fiddle, I realize the field you're trying to reset is an input type, so you can't change innerHTML - you have to work with value and placeholder and maybe even defaultValue when setting/resetting.
I would suggest just resetting value and showing the message by adding a class with [::after][1] css, but you could also show it by setting a new placeholder or even value [I don't thing setting the error message as value is a good idea at all though]. You can define the placeholder style in css as ::placeholder; but personally, I much prefer the ::after approach.

How to find a varible html element executing javascript in python

I'm trying to use 2Captcha service to solve an h captcha V2.
Works like this:
you get a value to solve the captcha
Then you find a textarea element in the HTML code to insert that value (here's my problem)
you insert the value in that element
You press submit button and the captcha is solved
First I'm going to present a working example, then I'll present where I have the problem.
This is the HTML code to find and insert the obtained value:
textarea id="h-captcha-response" name="h-captcha-response" style="display: none;"></textarea>
This is the python code used to insert the value:
value = get_value()
insert_solution = 'document.getElementById("h-captcha-response").innerHTML="' + value + '";'
driver.execute_script(insert_solution)
What this exactly does is taking you from this:
and this is the result:
Finally you press the submit button and it's done. This example works
This is my problem:
In my case the HTML document has a variable ID, like this one:
<textarea id="h-captcha-response-0tesbrpxsk8" name="h-captcha-response" style="display: none;"></textarea>
Notice that the id has an alphanumerical part (0tesbrpxsk8) that always changes making it more difficult to select.
I tried to find some regular expression to use inside of document.getElementById()
With no success
I also tried to use:
document.getElementByTagName("textarea").innerHTML=".....
I'm stucked here and tried other approaches with no success because I probably because I don't implement well those solutions or they just don't work.
I'll appreciate some insights, thanks
This will fill out all of those (recaptcha / hcaptcha):
driver.execute_script('''
let [captcha] = arguments
[...document.querySelectorAll('[name="h-captcha-response"],[name="g-recaptcha-response"]')].map(el => {
el.innerHTML = captcha
})
''', value)
Try this:
const textarea = document.querySelector('[id^="h-captcha-response-"]')
textarea.value = "This is inside the textarea!"
<textarea id="h-captcha-response-0tesbrpxsk8" name="h-captcha-response"></textarea>
First of all: You set the value of an textarea with textarea.value = "some value"
You should use document.querySelector() to select elements. (You have much more abilities there)
You can select id starting with, with this query: [id^="start"]

BootstrapToggle switch conditionally switch state

I'm trying to use bootstraptoggle in one of my pages. The initial state is off / disabled.
The page loads several boolean values and stores them as hidden text. Then I have a script which looks them up via their IDs. Upon that hidden text it should toggle the slider.
I was able to get the hidden text and make the conditional check but I'm not able to toggle the slider for some reason.
Here is my code:
$(document).ready(function () {
var flags = [];
var userID = '',
toggleSlider = '';
flags = document.querySelectorAll('*[id^="activeFlag_"]');
flags.forEach(function (flag) {
userID = flag.id.split('_')[1];
// This is where i search for the hidden text
if (flag.firstChild.data == 'True') {
// Nothing works here.
$('#activeToggle_' + userID).bootstrapToggle('toggle');
}
});
});
And this is the html code that I need to work with:
<p id="activeFlag_#user1">#item.activeFlag</p>
<div class="checkbox">
<label>
<input id="activeToggle_user1" type="checkbox" data-toggle="toggle" data-on="Enabled" data-off="Disabled">
</label>
</div>
Your code is too opaque without any data example.
However one thing could be a cause of its problem:
if (flag.firstChild.data == 'True') {
Try to replace it with:
if (flag.firstElementChild.data == 'True') {
Here you could find explanation:
The firstChild property returns the first child node of the specified node, as a Node object.
The difference between this property and firstElementChild, is that firstChild returns the first child node as an element node, a text node or a comment node (depending on which one's first), while firstElementChild returns the first child node as an element node (ignores text and comment nodes).
Note: Whitespace inside elements is considered as text, and text is considered as nodes (See "More Examples").
Update after example code was added
For the example code you provided, you should change the split argument:
userID = flag.id.split('_')[1];
to:
userID = flag.id.split('_#')[1];
Thanks to twain for initial jsfiddle. I have updated it accordingly: jsfiddle
I guess the problem is, that the following part does not use the correct id for the toggle $('#activeToggle_' + userID).bootstrapToggle('toggle');
Your html ID is activeToggle_user1, but the js part above will probably resolve to #activeToggle_1. So the text user is missing here.
I created a working fiddle here: https://jsfiddle.net/pbcrh5d2/
Ok, for some reason asp.net and javascript have a problem with coping together. I used asp.net to provide javascript to build the strings.
So I switched to the raw id that is used in the table.

How to style text via a javascript function when coming from an input field

I have one input field that facilitates a person having a conversation but playing both roles in the convo. I want to get as close as I can to what its like to have a text conversation, but I cannot seem to sort out how to style the text when it comes through.
As of the moment, the user types the text and hits one of two buttons, each is loaded with the following function to pull the text, create a div, text node, append them and place in the page.
I tried styling the initial input but that simply makes the input field styled, does not affect the actual output.
I tried adding style at each step of the way, to the variable I saved the input in, to the p, the div, the text node, and after placing it in the doc... each time the function failed.
I tried the attribute method and an innerhtml approach.
What would work? At minimum I would love the function to bold and right align the text. Next best would be to append it with the contents of an ng-app so it says Me: (text here), then My future self: (text here)... which I sense would just involve a string set to a variable.. but setting x = {{name}} caused the function to fail..
I know theres a way to use firebug to understand these failures, but I am not quite understanding that yet. Any suggestions?
<script>
function changeTextComment4(destination){
// to be modified from the above to change the location of the dump
// this function ADDS a comment from the comment field to the div w id comment near it...
var userInput = document.getElementById('userInputS1').value;
// get the input from the user
// 3 make the div a panel
var para = document.createElement("P");
// assignment of attributes
var t = document.createTextNode(userInput);
para.appendChild(t);
// add comment area
// place the item
var destination = document.getElementById(destination)
destination.insertBefore(para, destination.firstChild);
document.getElementById('userInputS1').value = "";
document.getElementById('userInputS1').focus();}
</script>
you can add style by referring to the selector
#userInputS1{
color : #F00;
}

Read more opens 1st one all the time

I've a page with about 10 short articles.
Each of them as a "Read More" button which when pressed displays hidden text
The issues I have at the moment is when I press the "Read More" on any of the 10 button it shows the 1st articles hidden content and not the selected one.
I think I need to set a unique ID to each article.. and the read more button be linked to it.. But I don't know how to set it.
I looked at this but couldn't get it working how to give a div tag a unique id using javascript
var WidgetContentHideDisplay = {
init:function() {
if ($('#content-display-hide').size() == 0) return;
$('.triggerable').click(function(e){
var element_id = $(this).attr('rel');
var element = $('#'+element_id);
element.toggle();
if (element.is(':visible')) {
$('.readmore').hide();
} else {
$('.readmore').show();
}
return false;
});
}
}
var div = documentElemnt("div");
div.id = "div_" + new Date().gettime().toString;
$(document).ready(function(){ WidgetContentHideDisplay.init(); });
OP Edit: Sorry, the original code wasn't in caps. I kept getting errors when trying to post, so I copied the code into Dreamweaver and it made it all caps for some reason.
Instead of selecting the element to toggle with an ID (i.e. $('#'+ELEMENT_ID)) you could setup a class for your item and use the class selection (e.g. $('.DETAILED-ARTICLE)') to select the child (or the brother, etc. depending how you built the HTML page).
In theory each ID should point to a single element but each class can be put to as many elements as you want.
If you're getting errors, read the errors and see what they are. Off of a quick read of your code, here are a couple things I noticed that will probably cause issues:
"documentElemnt" is misspelled, which will render it useless. Also, documentElement is a read-only property, not a function like you're using it.
toString is a function, not a property, without the parentheses (.toString()) it isn't going to function like you want it to.
Run the code, look at the errors in the console, and fix them. That's where you start.

Categories