How can we perform add class to a specific element?
I tried classList.add method in javascript but no luck 😞
await driver.findElement(By.css(".promotion-code-group.promo-shown .promo-selector")).classList.add("show");
TypeError: Cannot read property 'add' of undefined
I need your knowledge in selenium js I hope you guys can guide me through this. Thank you guys in advance!
You can edit an element's class list using execute_script() function.
In the second argument in setAttribute() you should put existing classes plus the new ones:
const element = await driver.findElement(
By.css(".promotion-code-group.promo-shown promo-selector")
);
await driver.execute_script(
"arguments[0].setAttribute('class', 'promotion-code-group promo-shown show')",
element
);
Related
This is my web address:
DM :
This is my locator for button accept all:
#FindBy( xpath = "//button[#data-testid = 'uc-accept-all-button']")
WebElement cookies;
This is HTML:
I use selenium 4 and Java. I try solution like this :
public void acceptAllCookies( ) {
cookies = driver.executeScript("return document.querySelector('#usercentrics-root').shadowRoot.querySelector("cookies")");
cookies.click();
}
But it does not work. I have error like this:
Any help please. I am a beginner so i see this for first time
I try to add more " marks like in solution I find here but then I get whole executeScript like text.
You would need to use escape sequence in "cookies"
See below
cookies = driver.executeScript("return document.querySelector('#usercentrics-root').shadowRoot.querySelector(\"cookies\")");
You have to either use single quotes around cookie in js.executeScript method if your css selector is cookie not java variable. And Cookie defined above is WebElement which can not be directly used while calling executeScript method.
cookies = driver.executeScript("return document.querySelector('#usercentrics-root').querySelector(button[data-testid = 'uc-accept-all-button'])");
And this does not solve your problem, please explain your issue in details.
The element Prihvatite sve button is within #shadow-root (open)
Solution
To click on the desired element you need to use querySelector() and you can use the following locator strategies:
driver.get("https://www.dm.rs/?wt_mc=sea.google.ads_generic.15146192844.132927670207.558370268562");
Thread.sleep(5000);
WebElement element = driver.findElement(By.cssSelector("#usercentrics-root"));
SearchContext context = element.getShadowRoot();
WebElement cookieAcceptAll = context.findElement(By.cssSelector("button[data-testid='uc-accept-all-button']"));
cookieAcceptAll.click();
References
You can find a couple of relevant detailed discussions in:
How to automate shadow DOM elements using selenium?
How to locate the First Name element within #shadow-root (open) using Selenium4 and Java
Problem
I am trying to use react-monaco-editor to render a json code. When I try to format the json , I was suggested the method: editor.getAction('editor.action.formatDocument').run() . The code that I use is
const editorDidMount = (editor, monaco) => {
setTimeout(() => {
console.log(editor);
editor.getAction('editor.action.formatDocument').run()
}, 300);
};
but I get the following error: Uncaught TypeError: Cannot read property 'run' of null
Could some one please help me understand why I am missing getAction method in the editor instance.
One other thing that I noticed is that, when checking in the context-menu(right-click).. I dont see the Format Document. Aslo the action editor.action.formatDocument is missing in the _actions object of the editor instance. Any help is much appreciated.
This seems to be an issue created by myself. I had to add the option format in the list of features of the monaco-editor-webpack-plugin(https://github.com/microsoft/monaco-editor-webpack-plugin). But one downside is I still cannot find the editor.getAction() method. Instead I had to use the editor.trigger() method to simulate a format action throught code.
Firstly, Karate UI automation is really awesome tool. I am kind of enjoying it while writing the UI tests using Karate. I ran into a situation where in, i was trying to fetch the shadowRoot elements. I read few similar posts related to javascript executor with karate and learnt that it is already answered. it is recommended to use driver.eval. But in Karate 0.9.5 there is no eval, it has script() or scriptAll(). I have gone through documentation couple of times to figure out how i can fetch element inside an element but no luck.
Using traditional selenium+java, we can fetch shadowRoot like this way:
something like shadowRoot which sits inside a parent element like div or body.
//downloads-manager is the tagname and under that downloads-manager, a shadowRoot element exists
The HTML looks like this. it is from chrome://downloads.
<downloads-manager>
#shadow-root(open)
</download-manager>
WebElement downloadManager =driver.findElement(By.tagName("downloads-manager");
WebElement shadowRoot= (WebElement)((JavaScriptExecutor)driver)
.executeScript("return arguments[0].shadowRoot",downloadManager);
So i tried the following in Karate UI
script("downloads-manager","return _.shadowRoot"); //js injection error
script('downloads-manager', "function(e){ return e.shadowRoot;}"); // same injection error as mentioned above.
def shadowRoot = locate("downloads-manager").script("function(e){return e.shadowRoot};"); //returns an empty string.
I bet there is a way to get this shadowRoot element using Karate UI but i am kind of running out of options and not able to figure out this.
Can someone please look into this & help me?
-San
Can you switch to XPath and see if that helps:
* def temp = script('//downloads-manager', '_.innerHTML')
Else please submit a sample in this format so we can debug: https://github.com/intuit/karate/tree/develop/examples/ui-test
EDIT: after you posted the link to that hangouts example in the comments, I figured out the JS that would work:
* driver 'http://html5-demos.appspot.com/hangouts'
* waitFor('#hangouts')
* def heading = script('hangout-module', "_.shadowRoot.querySelector('h1').textContent")
* match heading == 'Paul Irish'
It took some trial and error and fiddling with the DevTools console to figure this out. So the good news is that it is possible, you can use any JS you need, and you do need to know which HTML element to call .shadowRoot on.
EDIT: for other examples of JS in Karate: https://stackoverflow.com/a/60800181/143475
Reading the title you could think that it is easiest question ever, but it ain't so. Problem: I have to use the click() method on querySelectorAll. As I found in Google, it does have the method in the library, but once I wrote the next code I got an error:
const gsdCaseNewBtn = $("#someId")
const gsdCaseOldButton = document.querySelectorAll('input[value="SomeValue Case"]')
gsdCaseNewBtn.click(() => {
gsdCaseOldButton[0].click()
})
So, as you can see, I'm creating a new button and trying to attach to it the 'onclick' behavior of already existing button. Method click() doesn't work with the error ("this method does not exist on type ..."). I tried to resolve the issue with addEventListener, but I don't need to set the onclick behavior of the old button, I just have to get it. Do someone has the idea how to get this code work?
Requirements: gsdCaseOldButton can't be of jQuery type. gsdCaseNewBtn can be any type.
This should fix your code:
<script>
const gsdCaseNewBtn = document.querySelector("#someId")
const gsdCaseOldButton = document.querySelectorAll('input[value="SomeValue Case"]')
gsdCaseNewBtn.addEventListener('click', () => {
gsdCaseOldButton[0].click();
});
</script>
I tested this in localhost ( I did not have access to Jquery) so i am not certain what the cause of the problem was.
Please let me know if this fixed your code.
I want to create a generic function that notifies on errors
I can't seem to find a way to get the css selector from an ElementFinder member
Here's my function:
static waitForElementToExist(elementFinder: ElementFinder): SeleniumPromise<any> {
return browser.wait(until.presenceOf(elementFinder),
jasmine.DEFAULT_TIMEOUT_INTERVAL,
MyErrors.elementNotFound(<get element selector string>));
};
so I can return a meaningful error like:
could not found the element '.class-selector'
can anyone point me to the right direction please? :-)
If you use latest protractor, try:
MyErrors.elementNotFound(elementFinder.locator().toString())
More detail, please look locator() api.