Enable multiple files to be uploaded to a file input

Obviously, the input must have the multiple attribute for this to work.

The API is:

    page.uploadFile('#file_input', ['file1', file2'])

I haven't implemented support for multiple files in the page.filePicker
API because I couldn't work out how to get a return value of an array
of strings through the JS/C++ bridge.

https://code.google.com/p/phantomjs/issues/detail?id=256
1.8
Jon Leighton 2012-12-09 10:52:52 +00:00 committed by Ariya Hidayat
parent e8380e42d7
commit 487fbf3035
4 changed files with 33 additions and 7 deletions

View File

@ -432,6 +432,19 @@ function decorateNewPage(opts, page) {
this.setCookies(cookies);
});
/**
* upload a file
* @param {string} selector css selector for the file input element
* @param {string,array} fileNames the name(s) of the file(s) to upload
*/
page.uploadFile = function(selector, fileNames) {
if (typeof fileNames == "string") {
fileNames = [fileNames];
}
this._uploadFile(selector, fileNames);
};
// Copy options into page
if (opts) {
page = copyInto(page, opts);

View File

@ -93,7 +93,7 @@ public:
Q_UNUSED(option);
if (extension == ChooseMultipleFilesExtension) {
static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = QStringList(m_uploadFile);
static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = m_uploadFiles;
return true;
} else {
return false;
@ -115,7 +115,7 @@ protected:
Q_UNUSED(originatingFrame);
QString filePath = m_webPage->filePicker(oldFile);
QString choosenFile = !filePath.isNull() ? filePath : m_uploadFile;
QString choosenFile = !filePath.isNull() ? filePath : m_uploadFiles.first();
// Return the value coming from the "filePicker" callback, IFF not null.
qDebug() << "CustomPage - file choosen for upload:" << choosenFile;
@ -213,7 +213,7 @@ protected:
private:
WebPage *m_webPage;
QString m_userAgent;
QString m_uploadFile;
QStringList m_uploadFiles;
friend class WebPage;
};
@ -1105,13 +1105,13 @@ QString WebPage::footer(int page, int numPages)
return getHeaderFooter(m_paperSize, "footer", m_mainFrame, page, numPages);
}
void WebPage::uploadFile(const QString &selector, const QString &fileName)
void WebPage::_uploadFile(const QString &selector, const QStringList &fileNames)
{
QWebElement el = m_currentFrame->findFirstElement(selector);
if (el.isNull())
return;
m_customWebPage->m_uploadFile = fileName;
m_customWebPage->m_uploadFiles = fileNames;
el.evaluateJavaScript(JS_ELEMENT_CLICK);
}

View File

@ -255,7 +255,7 @@ public slots:
QObject *_getFilePickerCallback();
QObject *_getJsConfirmCallback();
QObject *_getJsPromptCallback();
void uploadFile(const QString &selector, const QString &fileName);
void _uploadFile(const QString &selector, const QStringList &fileNames);
void sendEvent(const QString &type, const QVariant &arg1 = QVariant(), const QVariant &arg2 = QVariant(), const QString &mouseButton = QString(), const QVariant &modifierArg = QVariant());
/**

View File

@ -476,9 +476,11 @@ describe("WebPage object", function() {
it("should handle file uploads", function() {
runs(function() {
page.content = '<input type="file" id="file">\n' +
'<input type="file" id="file2" multiple>';
'<input type="file" id="file2" multiple>\n' +
'<input type="file" id="file3" multiple>';
page.uploadFile("#file", 'README.md');
page.uploadFile("#file2", 'README.md');
page.uploadFile("#file3", ['README.md', 'LICENSE.BSD']);
});
waits(50);
@ -495,6 +497,17 @@ describe("WebPage object", function() {
return document.getElementById('file2').files[0].fileName;
});
expect(fileName).toEqual('README.md');
var files = page.evaluate(function() {
var files = document.getElementById('file3').files;
return {
length: files.length,
fileNames: [files[0].fileName, files[1].fileName]
}
});
expect(files.length).toEqual(2)
expect(files.fileNames[0]).toEqual('README.md');
expect(files.fileNames[1]).toEqual('LICENSE.BSD');
});
});