Waiting for hidden element to appear with selenium python
To explain the context, let us take an example of a login page.
Say a login page allows the user to enter the password only after 1 minute of wait time after entering the user name (assume please).
So, first only username field will be visible on the page. Then after 1 minute, password will be visible. But both the fields are present in the HTML when the page is loaded and the field ID doesn't change when it is hidden and when it is visible after wait time.
So, the following code gives out an "element not interactable" error for second operation (password).
WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID, 'username'))).send_keys(usr)
WebDriverWait(browser,70).until(EC.presence_of_element_located((By.ID, 'password'))).send_keys(pwd)
If I run this code one row at a time, while manually waiting for the password field to load on the page, then the code works. And the wait time is 60 seconds I have timed it.
But I run everything together as one file, then it almost in 2 seconds gives out an error that element is not interactable. Probably because until
finds the element ID immediately, even when it is hidden on the UI, but is present in the HTML.
How do we handle this delay?
You should change presence_of_element_located
to visibility_of_element_located
.
WebDriverWait(browser,100).until(EC.visibility_of_element_located((By.ID, 'username'))).send_keys(usr)
WebDriverWait(browser,100).until(EC.visibility_of_element_located((By.ID, 'password'))).send_keys(pwd)
should work.
There are several ExpectedConditions.
As you can see from their names presence_of_element_located
is waiting for presence of element matching the passed locator while visibility_of_element_located
will wait for visibility of that element.
Generally, you should always use visibility_of_element_located
since this method is waiting for element become visible and interactable while presence_of_element_located
will return the element still not fully rendered etc.