Selenium Python Shadow DOM input text - javascript

The website I am interacting with uses shadow DOMs. I can successfully interact with them for clicking buttons and in some cases can input text but I am currently stumped on this one.
The HTML looks like this
firefox html inspector view of one shadow dom input text box
I can input in the text fields with the following but the continue button doesn't enable for me to go to the next screen and if I manually click and place a space in the first box I get an error saying that to continue to the next page I need to fill in the second and third boxes (which have text but for some reason the webpage doesn't recognize that text is present). table with shadow dom inputs
shadowDOM1 = driver_local.execute_script("return document.querySelector('WN-input').shadowRoot.querySelector('input')")
str_valToSet = "arguments[0].value = '" + partNum + "';"
driver_local.execute_script(str_valToSet, shadowDOM1)
shadowDOM2 = driver_local.execute_script("return document.querySelectorAll('WN-input')[2].shadowRoot.querySelector('input')")
str_valToSet = "arguments[0].value = '" + str(num2buy) + "';"
driver_local.execute_script(str_valToSet, shadowDOM2)
shadowDOM3 = driver_local.execute_script("return document.querySelectorAll('WN-input')[1].shadowRoot.querySelector('input')")
str_valToSet = "arguments[0].value = '" + "CUSTX" + "';"
driver_local.execute_script(str_valToSet, shadowDOM3)
I was also able to click the text box input that is in the shadow root but when i go to send keys i get an error that "element is not reachable by keyboard". There is not a temporary overlay preventing me from typing, as far as i can tell there is not a permanent overlay, and I see no evidence of any attributes that would make it invisible to selenium (org.openqa.selenium.ElementNotInteractableException: Element is not reachable by keyboard: while sending text to FirstName field in Facebook)
fields = driver.find_elements(By.XPATH, '//tbody/tr/td/WN-input')
print("fields", fields)
print("field", fields[0])
shadowEl = expand_shadow_element(driver_local, fields[0])
print("shadowEl", shadowEl)
isVisible = WebDriverWait(shadowEl[1], maxDelay).until(EC.visibility_of_element_located((By.XPATH, "//input")))
print("isVisible", isVisible)
shadowEl[1].click()
time.sleep(2)
shadowEl[1].send_keys("blahblah")
In a different location within my code I successfully interact with a similar object this this (WN-input tag name) and was able to get it to open up the "next" button by typing some garbage text in a different input field that wasn't within a shadow DOM. When I try that technique for this case it blows away my text within my shadow DOM text input fields. I am not sure why this case seems to work and the case in question doesn't.
shadowDOM1 = driver_local.execute_script("return document.querySelector('WN-add-to-cart').shadowRoot.querySelector('WN-input')")
str_valToSet = "arguments[0].value = '" + str(num2buy) + "';"
driver_local.execute_script(str_valToSet, shadowDOM1)
try:
inputBox = WebDriverWait(driver_local, maxDelay).until(EC.element_to_be_clickable((By.XPATH, "//input[#placeholder='Search']")))
#inputBox = local_driver.find_element_by_xpath("//input[#placeholder='Search']")
inputBox.click()
inputBox.send_keys("text")
time.sleep(3)
After days of failed attempts and google search after google search I am finally ready to ask for help. Any thoughts?

Related

Add "Reply" to Twitter Reply Box Using jQuery

I am trying to add predefined text to the Twitter "reply" box:
but for some reason no matter what I try it won't work. Here is my code:
const element = document.querySelector("div.public-DraftEditorPlaceholder-root");
element.remove();
span.innerHTML = '<span data-text="true">' + s + '</span>';
it adds in the reply e.g.
But it does it in a way where the reply stays "disabled" until I key in text, but then it deletes the message my script added.
This is for a google chrome extension

Selenium preform double click + text edit using javascript

I want to automate canva.com site, using python's selenium library.
What I need to do ?
I need to insert data to fields inside canva (very simple). To force canva save my changes I need firstly DoubleClick the element, and only then update the text.
What is my problem ?
After I double click the element, it's changing ... and I can't change that python element's text. to change it, I need to find that element again and only than change it. - I Got an error that the element is not attached to the page.
def get_report_params_fields(driver, keys):
fields = {}
all_paragraphs = driver.find_elements_by_tag_name("p")
for paragraph in all_paragraphs:
key = re.sub(' +', ' ', paragraph.text.upper()).split(":")[0]
if key in keys:
if key in fields.keys():
fields[key].append(paragraph)
else:
fields[key] = [paragraph]
return fields
# update fields list
canva_fields = get_report_params_fields(driver)
# click the field to change
canva_fields[canva_key][task_index].click()
canva_fields[canva_key][task_index].click()
# update fields list
canva_fields = get_report_params_fields(driver)
# update the data
value = key + ": " + keys[key]
driver.execute_script("arguments[0].textContent = arguments[1];", canva_fields[canva_key][task_index], value)
The problem is that the get_report_params_fields (which just goes over all the paragraphs on the page and select the one I need) function is not efficient, so I want to use it only once.
So I am searching for a way to get the webelement I click using another way (using it's xpath, location, some other unique id of the webelement). I mean I need an option to find the same element again using the webelement properties, Without known the properties before (like checking the xpath in chrome, and I can't use the element's text because it is changing from time to time).
I thought about double clicking and changing the text inside oneliner javascript script, but I didn't found a way to do that.

Concatenate values from drop down along with user input

I have an issue with my code which might be quite obvious but I can't seem to find out the answer.
I have a drop down menu with pre-filled option values in it. Whenever a user clicks on any of the values, they get displayed on a text area using JavaScript. Here's my problem:-
If the user selects 'Hello World' from the drop down, it gets displayed in the text area. if the user types a string or number or anything after that in the text area, then selects the option 'How's your day going', it doesn't get concatenated to the text area, since the user made a change to the text area. How can I get it to concatenate the option values every time a different option is selected. Here's my code:-
HTML
<select name = 'type_of_call' id = 'type_of_call' onchange = 'run()'>
<textarea name = "comments" value = "comments" id = "comments" Required /></textarea>
JavaScript
function run(){
document.getElementById("comments").innerHTML += document.getElementById("type_of_call").value + ', ';
}
You want to set the textarea's value property, not the innerHTML property:
function run(){
document.getElementById("comments").value += ...;
}

Cefsharp to enter data to form

I need Cefsharp to do a small bit of automation. What I want to do is enter data into two textfield and then press a button. To do this I'm using javascript.
browser.ExecuteScriptAsync("var elems = document.getElementsByClassName('_fcn8k');");
browser.ExecuteScriptAsync("elems[0].click();");
Thread.Sleep(5000);
browser.ExecuteScriptAsync("var elems2 = document.getElementsByClassName('_kp5f7');");
browser.ExecuteScriptAsync("var elems3 = document.getElementsByClassName('_taytv');");
browser.ExecuteScriptAsync("elems2[0].value='" + userName + "';");
browser.ExecuteScriptAsync("elems2[1].value='" + userPassword + "';");
browser.ExecuteScriptAsync("elems[3].click();");
The code works, except for the fact that when I click the button the textfields are emptied and I get an error saying the data is wrong (since the fields are empty).
If I do it manually the data remains when the button is pressed. I really don't get why it disappears when I try to do this programmaticly.
Any ideas?

Making a FormBody Shrink and Expand Using JQuery and SharePoint

I am creating a form in sharepoint. I have an ms-FormBody for a text box. I would like for the user to be able to double click the box in order to expand the box and if they double click again, it will shrink back up. Again this is in SharePoint.
EDIT: Thanks to some help from #Thriggle I am very close to the goal I wanted with this project. The problem now is that Whatever you type will only stay on one line (t ext wrapping maybe?). Also The text box doesn't actually take up less space (This is not a big deal but if you can think of anyway to make the rest of the boxes move as this box resizes) and I was wondering if there is a way that the box will be small when program launches.
Based on your screenshots, I'm assuming that you're using Nintex Forms.
For Plain Text Multi-Line Fields
The following will work for plain text multiline fields, but not for rich text or enhanced rich text fields (neither of which are represented by an ordinary textarea element).
In your form settings, in the Custom JavaScript section, you can add the following code:
ExecuteOrDelayUntilScriptLoaded(function(){setTimeout(checkFieldExists,1000);},"sp.js");
function checkFieldExists(){
// Nintex forms load slowly; we'll hold off on running the code
// until we're able to access the element through the DOM.
var field = document.getElementById(DescriptionID);
if(field){
// The field exists, time to attach an event listener.
addExpansionToggleEvent(field);
}else{
// Wait a second, then check again.
setTimeout(checkFieldExists,1000);
}
}
function addExpansionToggleEvent(field){
field.style.height = ""; // remove the default height=100%
field.ondblclick = function(){
var rows = field.getAttribute("rows");
field.setAttribute("rows",+rows < 10 ? 10 : 1);
};
}
This is assuming you added a client ID of DescriptionID to the plain text multiline field that you want to toggle, as shown in your screenshot.
For Rich Text Multi-Line Fields
Rich text fields are (bizarrely) represented by iframes instead of textarea elements.
The following code can be added to your Custom JavaScript section to provide expand/shrink behavior upon double-clicking a rich text field, but note that this does not readjust the way other controls are laid out on the form to account for the field's new size... so it's not especially useful.
ExecuteOrDelayUntilScriptLoaded(function(){setTimeout(checkFieldExists,1000);},"sp.js");
function checkFieldExists(){
var iframes = document.querySelectorAll("iframe[title=\"Rich Text Editor\"]");
if(iframes.length > 0){
addExpansionToggleEvent(iframes);
}else{
setTimeout(checkFieldExists,1000);
}
}
function addExpansionToggleEvent(iframes){
for(var i = 0, len = iframes.length; i < len; i++){
var body = iframes[i].contentDocument.querySelector("body");
(function(container){
body.ondblclick = function(){
container.height = +(container.height) < 140 ? 140 : 30;
};
})(iframes[i]);
}
}
Again, this code is specifically targeted toward rich text field, and will not work for plain text or enhanced rich text fields.

Categories