Unable to click "Accept all" cookies in Selenium(python) in a pop-up - selenium

I am trying to click the Accept button on the pop-up for cookies.
Here's the code that I have tried:
driver.get(r'https://www.studydrive.net/')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.sc-gtsrHT.iETHdM"))).click()
Here's the error:
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
I have also tried using X-path but was not able to click on the button.
Any help is highly appreeciated.

This pop-up is on the shadow dom.
Selenium does not provide explicit support to work with Shadow DOM elements, as they are not in the current dom. That's the reason why we will get NoSuchElementException exception when try to access the elements in the `shadow dom.
With the following JavaScript this should work:
driver.get(r'https://www.studydrive.net/')
time.sleep(5)
accept_all_btn = driver.execute_script('''return document.querySelector('#usercentrics-root').shadowRoot.querySelector('button[aria-label="Accept All"]')''')
accept_all_btn.click()
See more explanations here and here

Related

Selenium clickable element clicked at wrong position?

We are waiting for a button identified by xpath to be clickable with:
ExpectedConditions.elementToBeClickable()
and then execute click on this button in Selenium.
We then get an error that:
another element would receive the click at position (x, y).
It is possible that this button is moving around slightly on the page during page loading as other buttons next to it are loading.
Why would Selenium report that the button is clickable and then not be able to click it? I understand that's what this condition is for. This execution happens in the same line.
How could we solve this problem?
Imagine that you want to interact with a button and that button is in middle of the page.
Case1:
You do not open the browser in full-screen mode through an automation script.
Then its position will not be in the middle of the page.
you can solve this issue by just introducing
driver.maximize_window()
Case2:
Maybe in the automation script, some pop up or ads shows up and that really hides the button in the background. In this case, you will likely encounter another element would receive the click at position (x, y).
Solution: You should determine what kind of pop up/Alert/ads they are and handle them separately then only you should interact with the intended button.
Case3:
It could also occur cause you might have open (let's say calendar to select a start/end date) and then because of that web elements that are just under the calendar view won't be accessible to selenium and only the Calendar view will get the click. [This should answer your query]
In General, I use actions class or JS to inject js code in the selenium script.
If you are using Selenium with Python then you can use
Use ActionChains:
ActionChains(driver).move_to_element(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "CSS here")))).click().perform()
Use execute_script:
wait = WebDriverWait(driver, 20)
button= wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "CSS here")))
driver.execute_script("arguments[0].click();", button)
In Python you'd need the below imports as well:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
Using ExpectedConditions.elementToBeClickable() allows our code to halt program execution, or freeze the thread, until the condition we pass it resolves. The condition is called with a certain frequency until the timeout of the wait is elapsed. This means that for as long as the condition returns a falsy value, it will keep trying and waiting. Thus Explicit waits allows us to wait for a condition to occur which inturn synchronises the state between the browser and its DOM Tree, and the WebDriver script.
Even with ExpectedConditions.elementToBeClickable() there can be instances while invoking click() on the desired element you may face either of the following errors:
Element ... is not clickable at point (415, 697). Other element would receive the click: <div class="cc-content">...</div>
or
WebDriverException: Element is not clickable at point (36, 72). Other element would receive the click
Reason and Solution
There can be numerous reasons for this error to occur and a couple of them and their remediation are as follows:
Though the element is within the Viewport but may be hidden behind the cookie banner. In such cases you have to accept the cookie consent before you interact with the desired element as follows:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("cookieConsentXpath"))).click();
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("elementXpath"))).click();
The element may be clickable but behind a loader. In such cases you have to wait for the loader to disappear before you interact with the desired element as follows:
new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("loader_cssSelector")));
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("element_cssSelector"))).click();

Want to check if an element is clickable in selenium without waiting for it

I have an element in a table. I want to check if the element is clickable or not.
I dont want to wait for it to be clickable. I just want to check if it is clickable.
Please help.
if it is enabled and visible to selenium then it should be clickable, shouldn't it be ?
Now if there is any pre condition i.e if you select I agree button then only you can click on Okay button. Those things are exception for this answer.
isDisplayed() Method in Selenium
The isDisplayed() method is used to check whether an element is displayed on a web page or not.
driver.findElement(By.locatorType(“path”)).isDisplayed();
isEnabled() Method in Selenium
isEnabled() method is used to check if the web element is enabled or disabled within the web page.
driver.findElement(By.locatorType(“path”)).isEnabled();
You can use a try/except like this
from selenium.common.exceptions import ElementNotInteractableException
driver.implicitly_wait(0)
try:
element.click()
except ElementNotInteractableException:
# TODO: put something here

Getting an error when clicking a link element on a web page by a Selenium script

When my Selenium script clicks a link element presented on a web page by click() method, I am getting the below error:
org.openqa.selenium.WebDriverException: Element is not clickable at point (36, 72).
This is my HTML code
<div id="targettab">
Book
</div>
This is my Selenium code:
driver.findElement(By.id("highlight-book")).click();
What am I doing wrong here? Could you please advise me about possible solutions? Thanks.
If element is present in lot of nested divs, rarely selenium driver will fails to click element. You can try clicking using Enter button.
driver.findElement(By.id("highlight-book")).sendKeys(Keys.Return);

Not able to locate web element on chrome browser's settings popup

I am trying to clear browser cache, for which i need to click on clear data button of browser setting popup, but, i am not able to write xpath for the button on chrome browser
i have tried inspecting the element to find out if the button is on a iframe but its not in iframe, so i have decided to try it with an with out iframe snippet, either of ways the element is not traces out in dom
public void clearBrowserCache() throws InterruptedException{
driver.get("chrome://settings/clearBrowserData");
Thread.sleep(2000);
System.out.println(driver.getWindowHandles());
String windowIds=driver.getWindowHandle();
// driver.switchTo().frame(windowIds);
driver.findElement(By.cssSelector(
[id=clearBrowsingDataConfirm]")).click();
}
Expected is that i should be able to click on the clear data button
Actual is that i am not able to find out the xpath for of the emlement
Depending on which version of chrome you are using, this could work:
driver.findElement(By.cssSelector("* /deep/ #clearBrowsingDataConfirm")).click();
However the /deep/ combinator is deprecated, so it may not work on newer Chrome's versions.
I answered how to reach inside the Shadow DOM in an other question.
You can read the whole thing at the link, but the basics are you create a "starting point" WebElement at the Shadow DOM via JavaScript, then all future look-ups reference it:
WebElement button = startingPoint.findElement(By.cssSelector("..."));

Click method is not working when using JavascriptExecutor in Selenium

I am clicking on the text box displayed on first page
WebElement txtBox = driver.findElement(By.xpath("---xpath---"));
txtBox.click();
Then after some block of execution I am getting the same textbox in new page on same window.
Here also I want to click on the text box.
I used JavascriptExecutor to do this scripting.
((JavascriptExecutor)driver).executeScript("arguments[0].click();", txtBox );
But while running the script I am getting an error message saying:
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
You need to execute driver.findElement() every time you reload the page.
This method returns WebElement which is integral part of current page. If you refresh browser or navigate to some other URL or even if element is deleted and attached again by some javascript on same page, previously found element cannot be used anymore.
Here you have official explanation of this exception: http://www.seleniumhq.org/exceptions/stale_element_reference.jsp
Stale Element exception comes after you want to interact with an element loaded previously. If you get webelement and then reload the page it gives this exception because it is not in a newly created page. It is better to click the web element without assigning it to a variable like:
driver.findElement(By.xpath("---xpath---")).click();