I was trying to automate a WordPress post content creation using Selenium Webdriver (Python). Unfortunately, I can not upload files in the post content. I have searched for the solution but most of them used send_keys which is not applicable for WP insert media (see image below). In the insert media, there are two options:
Select files
Drag files
I need a solution which will work for cross-platform (Windows, Linux etc).
I guess there might be a way using some jQuery, JS or something else. I am not very familiar with JS so I did not understand the solutions with JS.
P.S. I am working in Python, so a Python code will be helpful.
Here is the source for the media insert frame in case you need them:
<div class="media-frame-content">
<div class="uploader-inline">
<div class="uploader-inline-content no-upload-message">
<div class="upload-ui">
<h2 class="upload-instructions drop-instructions">Drop files anywhere to upload</h2>
<p class="upload-instructions drop-instructions">or</p>
Select Files
</div>
<div class="upload-inline-status">
<div class="media-uploader-status" style="display: none;">
<h2>Uploading</h2>
<button type="button" class="button-link upload-dismiss-errors"><span class="screen-reader-text">Dismiss Errors</span>
</button>
<div class="media-progress-bar">
<div></div>
</div>
<div class="upload-details">
<span class="upload-count">
<span class="upload-index"></span> / <span class="upload-total"></span>
</span>
<span class="upload-detail-separator">–</span>
<span class="upload-filename"></span>
</div>
<div class="upload-errors"></div>
</div>
</div>
<div class="post-upload-ui">
<p class="max-upload-size">Maximum upload file size: 32 MB.</p>
</div>
</div>
</div>
</div>
Finally, I've got a solution for WP add media file upload.
Actually, I have found that when the file selection window opens upon clicking the select files button, it generates a dynamic input field. Dynamic means, the ID for the input field is unique each time. Fortunately, the first part of the input field's ID remains same. For example, the ID is like html5_1bc7564i41pq5f7m1voce561a0e5. See the HTML below:
<input id="html5_1bc7564i41pq5f7m1voce561a0e5" style="font-size: 999px; opacity: 0; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;" multiple="" accept="" type="file"/>
So, what I did is, create an XPATH using the first part of the ID (html5_) and simply used send_keys and it worked perfectly. My XPATH is like:
input_file = "//input[starts-with(#id,'html5_')]"
The selenium code is:
driver.find_element_by_xpath(input_file).send_keys(file_path)
Here, file_path is the location of the file which I need to upload.
I missed the input field at the first place because it was not visible and did not realize that it is associated with the file upload. So I record the file upload steps with selenium IDE and found the dynamic input ID.
Thanks everyone, for all the suggestions and guidance.
drag and drop is possible:
Python Selenium WebDriver drag-and-drop
you can try move mouse and click "manually":
http://selenium-python.readthedocs.io/api.html#selenium.webdriver.common.action_chains.ActionChains.move_to_element
Here is the solution for you using AutoIT.
WordPress provides a select button to Upload New Media. So let us take help of that functionality.
On clicking "Select Files", File Upload dialog box would open up.
Pass the properties of File Upload dialog box to AutoIT exe.
AutoIT will fill up the filepath area with the selected file.
Now let the WebDriver click on the "Upload" button.
Let me know if this answers your query.
Related
On the website I have to select a specific time duration from the drop down menu as shown in the attached picture. I need to automate it using a Python script. I am having a script in which I need to add this one thing to make the script perfectly customize. Below is some info from the website highlighting the options.
<button id="duration" type="button" class="Blockreact__Block-sc-1xf18x6-0 Buttonreact__StyledButton-sc-glfma3-0 OKxo hJoTEY" aria-expanded="false" style="font-weight: 500; width: 100%;">
<div aria-hidden="true" class="Blockreact__Block-sc-1xf18x6-0 Flexreact__Flex-sc-1twd32i-0 cwzTQS jYqxGr">
<i value="calendar_today" size="24" class="Iconreact__Icon-sc-1gugx8q-0 irnoQt material-icons">calendar_today</i>
</div>
<div class="Overflowreact__OverflowContainer-sc-7qr9y8-0 jPSCbX" tabindex="-1">7 days</div>
</button>
The purpose over here is to change 7 days to 1 month using a Python script.
I believe you should be able to do this with selenium.
Generally, it's simple to make automation using Selenium to upload a file and there are many solutions for it.
But,
what I am facing for trouble is to implement web automation to upload a file through Dojo FileUploader.
<div class="ux uploader dnd fluid webDriver_uploader enforce-validity-marker-class mtc-uploader" data-dojo-attach-event="click:_onClickDomNode,drop:_onDropDomNode,dragover:_onDragOverDomNode,dragleave:_onDragLeaveDomNode,mouseenter:_onMouseEnterDomNode,mouseleave:_onMouseLeaveDomNode" id="Uploader_0" lang="en" widgetid="Uploader_0">
<i class="upload icon" data-dojo-attach-point="iconNode"></i>
<input type="file" name="">
<button type="button" class="ux button" data-dojo-attach-point="browseButtonNode" data-dojo-attach-event="blur:_onBlurBrowseButtonNode,click:_onClickBrowseButtonNode,focus:_onFocusBrowseButtonNode">Choose File
</button>
<button type="button" class="ux basic icon button hidden" data-dojo-attach-point="removeButtonNode" data-dojo-attach-event="click:_onClickRemoveButtonNode" title="Remove File">
<i class="trash icon">
<span class="description">Remove
</span>
</i>
</button>
<div class="placeholder label" data-dojo-attach-point="labelNode" data-dojo-attach-event="click:_onClickLabelNode">or drag and drop here
</div>
</div>
I've tried to control the file open dialog after clicking the Choose File button. But it seems like it's impossible to interact between the selenium and file open dialog.
I am working on Ubuntu 18.04
Selenium can interacts only with browser and when choose file button get clicked it will open file explorer ( which is in OS).
Workaround : instead of opening file explorer popup you can pass directly file path to selenium which it can upload automatically.
for Example : driver.findElementById().send_keys('filepath')
also you can use PyWinAuto to interact with file explorer for windows.(https://pywinauto.readthedocs.io/en/latest/).
Note: Using chrome 76, a new tab opens for every file
I have to download a lot of files, and I have to right-click and save link as. This works for the first file, but for subsequent files it right clicks at (0,0).
The download link only appears after clicking a download button. I have tried using implicit and explicit waits, however, this doesn't seem to be the problem as the first file works fine. I have used the element.location property to check the location right before the click however it is the same whether it clicks in the right spot or not.
Python
downloadButton.click()
#have tried time.sleep here doesn't work
downloadLink = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.XPATH, 'somepath'))
)
print(str(downloadLink.location)) #shows same correct location every time
actionChains.context_click(downloadLink).perform()
time.sleep(.1)
for i in range(4):
keyboard.send('down')
keyboard.send('enter')
time.sleep(1)
keyboard.send('enter')
Some HTML after the dl button has been clicked, can provide more if necessary
<div class="tab-content transparent no-padding-top margin-top">
<div class="tab-pane active" id="file">
<div data-bind="with: resource" class="form-horizontal form-panel">
<div class="form-group" data-bind="slideVisible: downloadedUrl() != ''" style="display: block;">
<label class="col-sm-3 control-label">Download Link</label>
<div class="col-sm-9">
<div class="bg-info padding">
<h4>Download version: <span data-bind="text: downloadName">Current Version</span></h4>
Click the link below to download this file.
<b>NOTE:</b> for larger files it may take a short time for the download to start.
<br>
<br>
<a style="word-break: break-all;" target="_blank" data-bind="attr: { href: downloadedUrl }, text: downloadedUrl" href="link">link</a>
</div>
</div>
</div>
hopefully that is somewhat formatted I copy-pasted from chrome console
Expected to right-click on the link element, clicks in the top left corner (0,0) instead
Test scenario:
1. Launch to site (https://app.box.com/files)
2. Login to site, page will redirect to All File page.
3. Click "Upload" button. ---- After click "upload files" and "upload folders" options appeared.
4. Click "upload Files" --- After click it windows file selection window display.
Then Upload files HTML code:
<ul id="ui-id-1" class="ui-menu ui-widget ui-widget-content ui-corner-all" style="position: absolute; top: 34px; left: 0.5px; display: block;" data-type="upload-menu" role="menu" tabindex="0" aria-activedescendant="ui-id-3">
<li class="ui-menu-item" data-type="upload-files-option" role="presentation" style="position: relative;" tabindex="-1">
<a id="ui-id-2" class="ui-corner-all" href="#" tabindex="-1" role="menuitem">Upload Files</a>
</li>
I use following code try to uploading file.
self.driver = webdriver.Firefox()
sDataFile = "D:\\TestData\\Test.txt"
self.driver.find_element_by_xpath("//a[#id='ui-id-2']").send_keys(sDataFile)
When I run this code the file cannot be uploaded successfully, webdriver will activate windows file selection dialog, but file cannot been uploaded. How to solve this problem?
When you are doing the below line make sure you are selecting the input component for send_keys.
self.driver.find_element_by_xpath
i.e. in html you will have a component like below. Make sure using xpath you select below element and then apply send_keys
<input type="file" />
I get an element isn't visible error:
ElementNotVisibleException: Message: u'Element is not currently visible and so may
not be interacted with'
For every find element line when I run this code:
from selenium import webdriver
browser = webdriver.Firefox()
browser.get('http://www.example.com')
browser.find_element_by_name('username').send_keys('myusername')
browser.find_element_by_name('password').send_keys('mypassword')
browser.find_element_by_class_name('welcomeLoginButton').click()
The HTML for the login section of the page looks like this:
<div class='welcomeLoginUsername'>
<div class='welcomeLoginUsernameLabel'><b>Username:</b></div>
<div class='welcomeLoginUsernameInput'><input type='text' name='username' tabindex='1'>
<br><a class='sf' href='javascript: void(0);' onclick='showUsernamePopup();'>
<b>Forgot Username?</b></a>
</div>
</div>
<div class='welcomeLoginPassword'>
<div class='welcomeLoginPasswordLabel'>
<b>Password:</b>
<br><span class='sf'>(It's cAsE sEnSitIvE!)</span>
</div>
<div class='welcomeLoginPasswordInput'>
<input type='password' name='password' tabindex='2'>
<br><a class='sf' href="javascript: void(0);" onclick="showPasswordPopup();">
<b>Forgot Password?</b></a>
</div>
</div>
</div>
<input type="submit" value="" class='welcomeLoginButton' style='border: 0px;
padding: 0px; margin: 0px;) no-repeat;' onclick='document.forms["login"].submit()'>
Selenium interacts with the web browser in a similar way that the user would. So if there is an html element you're trying to interact with that is not visible then the simplest explanation is that when youre writing your selenium code you're not interacting with the web page like a normal user would.
In the end this isn't about the html of your web page its about the DOM and an element's hidden attribute. I suggest you download firebug or some other html viewer program, and then highlight the button you want to press. Use the DOM lookup for the html viewer and go through the sign in process manually. Notice what you have to do to make the element visible in order to interact with it then mimic the same steps in your selenium code.
If it is a matter of the fact that you did everything you needed to do, but selenium is interacting with the web page faster than the javascript will make the element visible then there is a wait that you have to programmed in.
Naive way:
import time
time.sleep(1) # this is done in seconds
More scalable manner:
import time
welcome_button = browser.find_element_by_class_name('welcomeLoginButton')
wait_for_element_visibility(welcome_button).click()
def wait_for_element_visibility(element):
if element.is_visible():
return element
else:
for i in range(10):
if not element.is_visible():
time.sleep(.5)
else:
return element