-1

I am using Selenium with Python to automate a process to upload a file. There is an "Upload" button which is disabled by default and only becomes clickable when the file to be uploaded is chosen.

The HTML for Disabled Button is -

<button type="button" id="upload-button" data-bi-id="upload-button" class="ms-Button ms-Button--primary is-disabled root-296" disabled="" aria-label="Upload" aria-disabled="true" data-is-focusable="false">

And the HTML for button after it becomes clickable is -

<button type="button" id="upload-button" data-bi-id="upload-button" class="ms-Button ms-Button--primary root-437" aria-label="Upload" data-is-focusable="true" tabindex="0">

I am using -

WebDriverWait(browser, 15).until(EC.element_to_be_clickable((By.ID,"upload-button"))).click()

But its not working. I believe this is clicking on the disabled button (even though the file is chosen and the button has become clickable). I also tried -

WebDriverWait(browser, 15).until(EC.element_to_be_clickable((By.CLASS_NAME,"ms-Button ms-Button--primary root-437"))).click()

But this gives a TimeOut Exception. So what should I do to click this button after it becomes clickable. I have tried some solutions from the Internet, but none of them seem to be working.

5
  • How about By.CSS_SELECTOR? Commented May 12, 2021 at 19:13
  • @MuhdMairaj i tried that as well.....no luck. I even tried with XPATH. Commented May 12, 2021 at 19:15
  • Where you are getting this ID value profile.edit-picture.save-button . ID Should be this upload-button Commented May 12, 2021 at 19:17
  • @KunduK oh i'm sorry.....i pasted the wrong code here....that was a mistake on my part....i'll edit it right now.....i am using "upload-button" in id Commented May 12, 2021 at 19:24
  • @AnshulVerma : Did any solution work for you ? Commented May 13, 2021 at 4:30

4 Answers 4

1

Regarding the current version of your code, I think you may be right that it is clicking the button before it is really enabled. You have

WebDriverWait(browser, 15).until(EC.element_to_be_clickable((By.ID,"upload-button"))).click()

You are waiting for this element to be clickable. I wanted to try and figure out exactly what this meant so I looked at the source code. element_to_be_clickable is satisfied As soon as the element is "visible" and "enabled".

Visibility, I know, is defined as presence on the DOM and height/width both > 0. From your description it sounds like your button is immediately visible. So as soon as it is "enabled", element_to_be_clickable is satisfied and the wait will end.

This begs the question, what exactly determines whether an element is "enabled"? I found that selenium's is_enabled (which is required in the source code for element_to_be_clickable to pass), is essentially a negation of the W3C specification for disabled(). What it boils down to is this single line, which states that an element is "disabled" if The element is a button, input, select, textarea, or form-associated custom element, and the disabled attribute is specified on this element (regardless of its value).

That's it. Your element does have the "disabled" attribute, but it also has some other stuff that might cause it to be disabled -- the class name contains is-disabled, it's got aria-disabled="true" as well as data-is-focusable="false", all of which change by the time the button is fully clickable. I wonder if the disabled attribute goes away before something else that also causes the element to be disabled, so just as you said maybe your click is registering before the button is ready. To debug this I would try temporarily adding a hard wait, a few seconds long, after executing the WebDriverWait and before clicking the button.

For your class name,

WebDriverWait(browser, 15).until(EC.element_to_be_clickable((By.CLASS_NAME,"ms-Button ms-Button--primary root-437"))).click()

I suspect this is a dynamic class name, the root-437 part in particular, so maybe that's why that didn't work.

Finally, are you intending to upload from your filesystem by clicking the button? Because it can only interact with your web browser and can't browse a window on your OS, that doesn't work. There's a special way to upload files--you have to identify the file input element and send the absolute path of the file you want to upload to that element using send_keys().

Sign up to request clarification or add additional context in comments.

9 Comments

you are right about "root-437" being a dynamic class. I checked it, and it was changed to "root-437". Is this the reason why I cant click on the button? Also....about uploading the file...I have already taken care of that by using browser.find_element(By.CSS_SELECTOR,"input[type='file']").send_keys(cwd+"\\images\\1.jpg") So....how can I click on this button....i still dont understand
Good to know that the class is not dynamic, that is helpful. I didn't see that about the file upload in your first post so sorry for bringing that up. As I said above, To debug this I would try temporarily adding a hard wait, a few seconds long, after executing the WebDriverWait and before clicking the button.
What do you mean by hard wait?? Are you referring to Implicit Wait or time.sleep(10)?? I have tried both of these.
The time.sleep(10). The big piece that's missing to figure this out is that we don't have the HTML of the page or a link to it. is it possible one or more of your elements is inside an iframe?
Please try to avoid sarcasm and condescension. I understand the issue is frustrating, but there are a lot of people dedicating time to hopefully get this solved.
|
1

It seems you are using wrong ID value.

WebDriverWait(browser, 15).until(EC.element_to_be_clickable((By.ID,"upload-button"))).click()

Or use this css selector

WebDriverWait(browser, 15).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#upload-button[data-is-focusable='true']"))).click()

3 Comments

I was initially using the correct ID value....but then I was testing a little and pasted the wrong ID here.....although I have edited it now. Also, using css selection doesnt work either.....its giving TimeOut exception.
CSS selector as the approach cannot be the reason of timeout exception. The reason may be wrong selector. It does not matter css or xpath
Selector suggested by Kunduk is correct. Update your questionwith more data.
0

As you can see, the button element while it is still disabled contains class is-disabled and contains attribute disabled and it doesn't contain these attributes when it is enabled.
So the expected condition is to locate the element defined by the following xpath:

//button[@id='upload-button' and(not(contains(@class,'is-disabled'))) and(not(@disabled))]

In other words you should use the following:

WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.XPATH, "//button[@id='upload-button' and(not(contains(@class,'is-disabled'))) and(not(@disabled))]")))

You can locate the enabled button based on absence of one of the two attributes mentioned as well.

6 Comments

I tried this, but it didnt work. Although there were no errors shown. So does that mean that the presence of the Enabled Button is found? But when I tell the code to click on it....it doesnt work....the program just terminates without any errors.
Have you tried waiting for this element to be clickable? I mean locating it according to the absence of disabled attributes and this element to be clickable? Or visible?
yeah....just did....it doesn't work
Really strange. It would be interesting to debug this on real web page but I can't...
This might be similar to google's change profile picture option. Do you think that could help?
|
0

Try clicking without explicit wait, using implicit:

driver.implicitly_wait(15)
driver.find_element_by_xpath('//button[@data-is-focusable="true"]').click()

Or

driver.implicitly_wait(15)
driver.find_element_by_xpath('//button[@data-is-focusable="true" and @tabindex="0"]').click()

If this won't help, add more details to your question.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.