WebDriverWait not working as expected
Once you wait for the element and moving forward as you are trying to invoke click()
method instead of using presence_of_element_located()
method you need to use element_to_be_clickable()
as follows :
try:
myElem = WebDriverWait(self.browser, delay).until(EC.element_to_be_clickable((By.XPATH , xpath)))
Update
As per your counter question in the comments here are the details of the three methods :
presence_of_element_located
presence_of_element_located(locator) is defined as follows :
class selenium.webdriver.support.expected_conditions.presence_of_element_located(locator)
Parameter : locator - used to find the element returns the WebElement once it is located
Description : An expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible or interactable (i.e. clickable).
visibility_of_element_located
visibility_of_element_located(locator) is defined as follows :
class selenium.webdriver.support.expected_conditions.visibility_of_element_located(locator)
Parameter : locator - used to find the element returns the WebElement once it is located and visible
Description : An expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0.
element_to_be_clickable
element_to_be_clickable(locator) is defined as follows :
class selenium.webdriver.support.expected_conditions.element_to_be_clickable(locator)
Parameter : locator - used to find the element returns the WebElement once it is visible, enabled and interactable (i.e. clickable).
Description : An Expectation for checking an element is visible, enabled and interactable such that you can click it.
Webdriverwait is not working as expected
New release/s of selenium is not stable , I used the old version of selenium which is 2.53 so that the code webdriverwait will work as expected.
webdriver implicitWait not working as expected
Use below method to wait for a element:
public boolean waitForElementToBePresent(By by, int waitInMilliSeconds) throws Exception
{
int wait = waitInMilliSeconds;
int iterations = (wait/250);
long startmilliSec = System.currentTimeMillis();
for (int i = 0; i < iterations; i++)
{
if((System.currentTimeMillis()-startmilliSec)>wait)
return false;
List<WebElement> elements = driver.findElements(by);
if (elements != null && elements.size() > 0)
return true;
Thread.sleep(250);
}
return false;
}
And below method is to wait for page load:
public void waitForPageLoadingToComplete() throws Exception {
ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript(
"return document.readyState").equals("complete");
}
};
Wait<WebDriver> wait = new WebDriverWait(driver, 30);
wait.until(expectation);
}
Let's assume you are waiting for a page to load. Then call the 1st method with waiting time and any element which appears after page loading then it will return true
, other wise false
. Use it like,
waitForElementToBePresent(By.id("Something"), 20000)
The above called function waits until it finds the given element within given duration.
Try any of below code after above method
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));
or
wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>));
Update:
public boolean waitForTextFiled(By by, int waitInMilliSeconds, WebDriver wdriver) throws Exception
{
WebDriver driver = wdriver;
int wait = waitInMilliSeconds;
int iterations = (wait/250);
long startmilliSec = System.currentTimeMillis();
for (int i = 0; i < iterations; i++)
{
if((System.currentTimeMillis()-startmilliSec)>wait)
return false;
driver.findElement(By.id("txt")).sendKeys("Something");
String name = driver.findElement(by).getAttribute("value");
if (name != null && !name.equals("")){
return true;
}
Thread.sleep(250);
}
return false;
}
This will try entering text in to the text field till given time in millis. If getAttribute()
is not suitable in your case use getText()
. If text is enetered then it returns true. Put maximum time that u can wait until.
Selenium WebDriver wait doesn't work with expected conditions for cookie policy window
You are waiting for the cookie policy close button twice. Your code closes the cookie policy panel first time so it keeps waiting for the button to be clickable again but it is not going to be clickable after you have closed it. That is why you are getting exception.
Try the following:
driver.get("https://www.marketwatch.com/watchlist")
wait = WebDriverWait(driver,30)
wait.until(EC.element_to_be_clickable((By.CLASS_NAME,"gdpr-close"))).click()
wait.until(EC.element_to_be_clickable((By.ID, "wl-scrim-start"))).click()
wait.until(EC.presence_of_element_located((By.ID, "profilelogin"))).click()
It will take you to the login page without any exception.
Selenium Python - Explicit waits not working
This version successfully loads the site, waits for it to render, then opens the side menu. Notice how the wait.until method is is used successfully wait until the page is loaded. You should be able to use the pattern below with the rest of your code to achieve your goal.
CODE
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
driver.get("https://www.target.com/")
wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#leftNavigation > ul:nth-child(2)")))
button = driver.find_element_by_xpath("""//*[@id="js-toggleLeftNavLg"]""")
button.click()
time.sleep(5)
driver.quit()
Expected Condition WebDriverWait Python Selenium Question
You were close.
The WebDriverWait
expect a driver instance as first parameter. The WebElement
object has the driver object in its instance and also implement most of the WebDriver methods.
Having that in mind, you can create a new WebDriverWait
and pass your element instead of the driver.
Instead of:
elements[x].WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR,'li.price-current')))
Use:
WebDriverWait(elements[x], 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR,'li.price-current')))
Related Topics
Can Python Select What Network Adapter When Opening a Socket
How to Remove Items from a List While Iterating
How to Print Without a Newline or Space
What Is Truthy and Falsy? How Is It Different from True and False
Why Is the Output of My Function Printing Out "None"
How to Put the Legend Outside the Plot
Python, Unicode, and the Windows Console
Why Can a Function Modify Some Arguments as Perceived by the Caller, But Not Others
Getting the Name of a Variable as a String
What Does _All_ Mean in Python
Calling a Python Script from Command Line Without Typing "Python" First
What Are Metaclasses in Python
Accessing the Index in 'For' Loops
How to Parse Xml and Get Instances of a Particular Node Attribute
How to Type Hint a Method With the Type of the Enclosing Class
What Happens When Using Mutual or Circular (Cyclic) Imports in Python