I am creating an automation with selenium Webdriver. But it does not recognize the .SendKeys() method because of the #shadow-root.
Then I am using javascriptExecutor.executeScript and the only way that I found to insert a text with all the tags which I need was "InsertAdjacentHTML".
until here it is just perfect!!! The text is there exactly as I want, it is in the resolution notes.
The problem comes to the next step, when I click on the btn resolve or save, it will keep asking me to add the resolution notes. although the notes are there, I can see them!
At this point the automation breaks. And then if I manually give just one click upon the resolution notes, and click on btn resolve or save, it will recognize the text and will be able to save it.
My question is: Why the insertAdjacentHTML is not been recognized by the DOM as a text in the first stage. how to fix that?
Should I give a command to refresh or reload the page ??? If I do that, I think I will lost the text! Is there a way to do it?
Please, if you have faced the same problem on your automation, let me know how to fix it.
If you don't use it for automations, but you know how to fix it, let me know too.
Thank you so much!
String eng1 = "return document.querySelector(\"sn-workspace-layout > sn-workspace-main > sn-workspace-content\")" +
".shadowRoot.querySelector(\"now-record-form-connected\").shadowRoot.querySelector(\"sn-form-internal-workspace-form-layout\")" +
".shadowRoot.querySelector(\"now-record-form-blob\").shadowRoot.querySelector(\"sn-form-internal-tabs\")" +
".shadowRoot.querySelector(\"sn-form-internal-tab-contents\").shadowRoot.querySelector(\"now-record-form-section-column-layout\")" +
".shadowRoot.querySelector(\"now-record-html-editor\").shadowRoot.querySelector(\"iframe\")" +
".contentDocument.activeElement.insertAdjacentHTML(\"afterBegin\", \"<p>****************************************************</p>");";
WebElement notes = (WebElement) jsExecutor.executeScript(eng1);
Related
First of all, I am not a programmer. I do not know Javascript at all. I'm trying to create a Chrome extension that modifies my browser tab's title, by taking a specific string on a webpage. I know how to create Chrome extensions (just barely) and I just need to modify the Javascript to do what I want (which I do not know how).
I found the following script online and am trying to modify it but can't figure out how to get it working. Here is the script:
https://pastebin.com/dY1LSdjT
// Fire this event any time the mouse is moving. Sucks for performance, but it's a better experience
document.addEventListener("mousemove", function() {
// This will get us the banner
let bannerTextElements = document.getElementsByClassName("dijitReset dijitInputField dijitInputContainer");
console.log(bannerTextElements);
console.log(bannerTextElements[0]);
if (bannerTextElements[0]) {
console.log("ok!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
console.log(bannerTextElements[0].innerHTML);
// This will get us the text
let bannerTextLine = bannerTextElements[0].getElementsByClassName("dijitReset dijitInputInner");
console.log(bannerTextLine);
document.title = bannerTextLine[0].innerHTML
}
}, false);
And here's the website viewed in developer mode. I would like to get the text "blahhhh" and use that for the title of my browser tab.
Below is a different webpage and the difference here is that the "div class" names will change. The numbers in those class will change to different numbers, but the structure and the overall name remains the same. For example, "ms-Button-label label-549" may change to "ms-Button-label label-640". This happens whenever you refresh the page. I found that the "viewport" id name doesn't change though, so I think if we can use that as a reference and then just look at the nested div classes and reference them and extract the value (in this case Crystal Mountain).
Fixing your code
You got like 95% of everything you need.
The one thing you are missing right now is that the fact that an input element does not posses an "innerHTML" (That is why it isn't closed like this: <input>renderedText</input>). Instead you want to check for it's value:
document.title = bannerTextLine[0].value;
Some Improvements:
Search by ID
You have a well defined input which can be more easily obtained by looking it up using the id:
let bannerTextLine = document.getElementById('lanDeviceIndex_searchBox');
End result:
const bannerTextLine = document.getElementById('lanDeviceIndex_searchBox');
bannerTextLine.addEventListener("blur", function() {
if (bannerTextLine != null) {
document.title = bannerTextLine.value;
}
});
This is the entire JS code. Note that I changed the event to blur which activates when the form is left, this should be optimal for your case.
My Question is
How to remove the last undoing from undoing stack?
I'm Doing something in CKEditor.And I'm using
editor.fire('lockSnapshot');
and
editor.fire('unlockSnapshot');
My Original HTML content is
After Change Something(put del/ins tag using MY CODE)
And I add something in the editor and doing undo it will change like this.
And this is my code.
editor.fire('lockSnapshot');
$(currentSpanNode).after('<ins class="ice-ins ice-cts">' + spanInnerText + '</ins>');
$(currentSpanNode).after('<del class="ice-del ice-cts">' + spanOuterHTML + '</del>');
$(currentSpanNode).remove();
editor.fire('unlockSnapshot');
'currentSpanNode' have a particular span Node.
I want to know..
Is there any possible way to Remove/Update Stack of undo?
If possible tell me the way.
Please, anyone get me out of this issue.
Hey guys I am trying to click on an element called practitioner access on my company's web site and I have tried looking up documentation on stack over flow and have not figured out how to do this exactly I need help. What I am trying to do is click on the practitioner access popup/drop down and I have not been able to find the code to do it. Please see epic at the bottom:
This is how far I have gotten so far but protractor cant find the element
var pracaccess = element(by.xpath("//contains(#onclick, 'Practitioner Access')"))
pracaccess.click();
browser.sleep(10000);
I have tried to use these site to try and help myself but I can't piece it together. Any help would be appreciated. I am new to xpath as well.
new info to possibly help:
Here is a more expanded view
Also this is what it looks like in vb-script but its basically the same any suggestions?
Browser("ADP_2").Page("ADP_3").Link("html tag:=A","innertext:=Practitioner Access").WaitProperty "visible",True,30000
Browser("ADP_2").Page("ADP_3").Link("html tag:=A","innertext:=Practitioner Access").Object.Click
This XPath expression would look for a tag with the contains tag name, which does not exist. Instead, you've actually meant:
//a[contains(#onclick, 'Practitioner Access')]
Or, there is a nicer way to locate an a element by the link text:
element(by.linkText("Practitioner Access"))
The answer by alecxe is correct but if you want it to be as xpath:
element(by.xpath('//a[text()="Practitioner Access"]'));
I have some crazy app done almost 100% by manipulating the DOM and I find myself in the unfortunate position of changing something in it. As there are probably around 100 different scripts that do God knows what, I have no clue in which file should I look to make my changes. So, I want to ask, is there a way (using Firebug maybe or something similar) to know where a specific piece of html was generated? I'm a C developer, so I'm not very good at this, it drives me crazy.
Are all the elements added at the page load, or partially in the response to the user input? (clicking etc.)
for stuff added with the response to your actions, you can use Firebug's "Break On Next" button in the "Script" tab. To active BON you have to click it, or, in just-shipped Firebug 1.10.0a8, use keyboard shortcut ALT-CTRL-B (useful when you have event listeners bound to mouse movements). Then, when any piece of JS is going to be executed in reaction to your click etc., you will hit a breakpoint.
for stuff added at page load time, you may use the trick of extending the native functions (this might sound crazy - yeah it is, don't do it in production!) like appendChild, insertBefore, replaceChild. Just insert the appropriate code at the very top of your main HTML file, so all the code below will "see" the change.
Unfortunately, this does not work in Firefox due to a bug. But works in Opera and I guess in Chrome as well.
When you extend the native function, you can inject any code before really adding the node to the page. For instance, call console.log or create a breakpoint, to inspect the current page state. You can try playing with breakpoints to see the available variables properties inside those function to adjust what you push to console.log.
For this code:
<!doctype html>
<html>
<head>
<script type="text/javascript">
// this should work in Firefox but it does not -- https://bugzilla.mozilla.org/show_bug.cgi?id=618379
// works at least in Opera, probably Chrome too
Node.prototype._appendChild = Node.prototype.appendChild;
Node.prototype.appendChild = function(child) {
console.log("appending " + child + " to " + this);
return this._appendChild(child); // call the original function with the original parameters
}
// this works in Firefox
document._createElement = document.createElement;
document.createElement = function(tagName){
console.log("creating " + tagName);
return this._createElement(tagName);
}
</script>
</head>
<body>
<script type="text/javascript">
var p = document.createElement("p");
p.appendChild( document.createTextNode("abc"));
document.body.appendChild(p);
</script>
</body>
</html>
Opera outputs:
creating p appendChild.html:14
appending [object Text] to [object HTMLParagraphElement] appendChild.html:7
appending [object HTMLParagraphElement] to [object HTMLBodyElement] appendChild.html:7
To overcome the weakness of Firefox (that you can't override appendChild), you may use the trick: place the code below instead in the top of your HTML
<script>
Node.prototype._appendChild = function(child) {
console.log("appending " + child + " to " + this);
return this.appendChild(child)
};
</script>
and then, use Fiddler proxy by creating auto-responders (WMV tutorial, 9.9 MB) where you manually replace all calls to .appendChild with ._appendChild (you can use Notepad++ for "find replace in all opened files"). Creating auto-responders and hand-tampering requests can be mundane, but it's extremely powerful. To quickly create auto-responder rule, load the page when Fiddler is active, then drag'n'drop files as in the picture below. For each file, right click and choose "Generate File" from menu (this will put a file on the desktop) or create a file by yourself in different location. (it's good to open Fiddler-generated files and remove response headers from them; BTW "Generate file" puts real contents only if the response header was 200, so make sure to load the page with CTRL-F5 to skip the cache).
In Chrome you can inspect an element and right click on it. This menu gives you some options to break when something below the element is changed or when it's own attributes change. Maybe one of those breakpoints will find what you are looking for?
Assuming you've got access to the raw (hopefully un-minified/obfuscated) JS files, maybe just search them for text strings related to DOM manipulation and/or attributes of the node you're trying to find the creation of? I'd try things like "appendChild" "createElement" and the node's ID/class names.
You could also set break points all over the script files, and step through them as the page loads to help you narrow down where to look. Might help to start by just "pausing" the JS execution and stepping through from the very beginning.
If you can share the code (a link to the live site would do fine) I'd be happy to take a look.
If you are using the jQuery framework in your javascript to make the DOM changes then you may find the fireQuery plugin for FireBug in the firefox browser may get you the information you need.
Example:
It adds additional information to the standard HTML view by superimposing additional jquery element information to the display to provide a deeper insight into how your javascript is amending the page content.
I hope that helps you out.
I'm trying to change the value of a text input field based on user actions. I'm doing it like this:
document.getElementById(textFieldID).value = newValue;
It isn't quite working -- the original text in the field remains on the screen, unchanged. However, when I submit the form, it behaves as though the value was indeed changed correctly. (And a debug alert confirms that yup, I'm hitting that bit of the code and passing in the right field ID and text value.) Anybody have any insights? Is there something I need to be doing to redraw the input element?
Edit: Per Jeff B's request, and per the fact that this seems to have everybody stumped, here's some relevant bits of code:
<script LANGUAGE="JavaScript" TYPE="text/javascript">
function changeText(changeSelector)
{
var myindex = document.getElementById(changeSelector+"Recent").selectedIndex;
var SelValue = document.getElementById(changeSelector+"Recent").options[myindex].value;
document.getElementById(changeSelector).value = SelValue;
document.getElementById("historicalText").value = SelValue;
document.getElementById("historicalTextSelect").value = changeSelector;
}
</script>
<input onChange="updateScrollingPreview1217(this); return true;" type="text" id="crawlMsg1217" name="crawlMsg1217" size="60" maxlength="1000" value="">
<select id="crawlMsg1217Recent" name="crawlMsg1217Recent" onchange="javascript:changeText('crawlMsg1217');">
[options go here]
</select>
And that "onChange" handler isn't what's gumming up the works; I get the same behavior with or without it.
Edit 2: It looks like the problem is being caused by "JSpell", a third-party spelling checker our product uses. (I'm told that clients prefer using it to a spellcheck built into the browser; go figure.) It appears to be slightly misconfigured on my test machine, so I'm going to try straightening that out and praying that it makes the problems go away. If it doesn't ... should be interesting.
Edit 3: Yup. Fscking JSpell. Just posted a complete answer for the sake of posterity, will accept it tomorrow when I'm allowed. My thanks to everybody who tried to help; +1's all around, wish I could give more.
I have confirmed that the culprit is indeed JSpell, and that the precise trouble spot is this line:
window.onload=jspellInit;
Despite the prayers mentioned in Edit 2 above, making sure it was configured correctly did NOT make the problem go away. And this line is indispensable to JSpell's functionality. I don't know if JSpell always hoses Javascript functionality this way, or if there's some sort of perfect storm of factors that's causing it to pick a fight with my page, but that is indeed the source of my problems.
My thanks to everybody who tried to help. This was obviously a bit of a no-win in terms of getting the right answer, since it was caused by a component that was seemingly entirely unrelated and thus didn't get mentioned by me, but you at least confirmed that I was (in theory) doing things right and not simply going insane.
Is the document's id actually "textFieldID" or is "textFieldID" a javascript variable that contains the ID of the text input to change? If it is not a variable, I believe you should make it:
document.getElementById('textFieldID').value=newValue;
It's hard to debug this without the context, since the code you have ought to work fine. Can you confirm that you've got the right node by doing something like:
document.getElementById(textFieldID).style.border = "4px solid red";
What does any other element on the page have a name attribute that is the same as the id?
Internet Explorer 8 and later. In IE8
mode, getElementById performs a
case-sensitive match on the ID
attribute only. In IE7 mode and
previous modes, this method performs a
case-insensitive match on both the ID
and NAME attributes, which might
produce unexpected results. -
http://msdn.microsoft.com/en-us/library/ms536437%28VS.85%29.aspx
Try alerting your the nodeName and id ofr the returned element and make sure its the input you expect.
Use div element instead of textfield. I had same problem, my textfield which is changed with another script wasnt get the right value. you can easily use any div element like textfield with some CSS. than you can get the value from div using innerHTML.