⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 243340 in webkit


Ignore:
Timestamp:
Mar 21, 2019, 3:54:25 PM (7 years ago)
Author:
BJ Burg
Message:

Web Automation: support uploading non-local file paths
https://bugs.webkit.org/show_bug.cgi?id=196081
<rdar://problem/45819897>

Reviewed by Devin Rousso and Joseph Pecoraro.

To support cases where supplied file paths do not exist on the session host, add support for
receiving file contents via Automation.setFilesToSelectForFileUpload.

  • UIProcess/Automation/Automation.json: Add new parameter.
  • UIProcess/Automation/WebAutomationSession.h:
  • UIProcess/Automation/WebAutomationSession.cpp:

(WebKit::WebAutomationSession::setFilesToSelectForFileUpload):
Add support for receiving and saving file contents to a temporary directory. Rewrite the used paths so
that WebCore knows to look at the revised paths where the file contents have been saved.

(WebKit::WebAutomationSession::platformGenerateLocalFilePathForRemoteFile):
Since WebKit does not have usable FileSystem implementations for all ports, shell out the actual
saving of base64-encoded file data. Provide a Cocoa implementation, since that's what I can test.

  • UIProcess/Automation/cocoa/WebAutomationSessionCocoa.mm:

(WebKit::WebAutomationSession::platformGenerateLocalFilePathForRemoteFile):
Use WTF::FileSystem to create a temporary directory, and use Cocoa methods to actually write the file.

Location:
trunk/Source/WebKit
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r243339 r243340  
     12019-03-21  Brian Burg  <bburg@apple.com>
     2
     3        Web Automation: support uploading non-local file paths
     4        https://bugs.webkit.org/show_bug.cgi?id=196081
     5        <rdar://problem/45819897>
     6
     7        Reviewed by Devin Rousso and Joseph Pecoraro.
     8
     9        To support cases where supplied file paths do not exist on the session host, add support for
     10        receiving file contents via Automation.setFilesToSelectForFileUpload.
     11
     12        * UIProcess/Automation/Automation.json: Add new parameter.
     13
     14        * UIProcess/Automation/WebAutomationSession.h:
     15        * UIProcess/Automation/WebAutomationSession.cpp:
     16        (WebKit::WebAutomationSession::setFilesToSelectForFileUpload):
     17        Add support for receiving and saving file contents to a temporary directory. Rewrite the used paths so
     18        that WebCore knows to look at the revised paths where the file contents have been saved.
     19
     20        (WebKit::WebAutomationSession::platformGenerateLocalFilePathForRemoteFile):
     21        Since WebKit does not have usable FileSystem implementations for all ports, shell out the actual
     22        saving of base64-encoded file data. Provide a Cocoa implementation, since that's what I can test.
     23
     24        * UIProcess/Automation/cocoa/WebAutomationSessionCocoa.mm:
     25        (WebKit::WebAutomationSession::platformGenerateLocalFilePathForRemoteFile):
     26        Use WTF::FileSystem to create a temporary directory, and use Cocoa methods to actually write the file.
     27
    1282019-03-21  Youenn Fablet  <youenn@apple.com>
    229
  • trunk/Source/WebKit/UIProcess/Automation/Automation.json

    r240554 r243340  
    620620            "parameters": [
    621621                { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." },
    622                 { "name": "filenames", "type": "array", "items": { "$ref": "string" }, "description": "Absolute paths to the files that should be selected." }
     622                { "name": "filenames", "type": "array", "items": { "type": "string" }, "description": "Absolute paths to the files that should be selected." },
     623                { "name": "fileContents", "type": "array", "items": { "type" : "string" }, "optional": true, "description": "An array of Base64-encoded binary data for each file to be selected. If this property is provided, it is assumed that 'filenames' are not real file paths on the session host's filesystem, and this binary data will be used instead." }
    623624            ]
    624625        },
  • trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp

    r243094 r243340  
    12391239}
    12401240
    1241 void WebAutomationSession::setFilesToSelectForFileUpload(ErrorString& errorString, const String& browsingContextHandle, const JSON::Array& filenames)
     1241void WebAutomationSession::setFilesToSelectForFileUpload(ErrorString& errorString, const String& browsingContextHandle, const JSON::Array& filenames, const JSON::Array* fileContents)
    12421242{
    12431243    Vector<String> newFileList;
    12441244    newFileList.reserveInitialCapacity(filenames.length());
    12451245
    1246     for (const auto& item : filenames) {
     1246    if (fileContents && fileContents->length() != filenames.length())
     1247        SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "The parameters 'filenames' and 'fileContents' must have equal length.");
     1248
     1249    for (size_t i = 0; i < filenames.length(); ++i) {
    12471250        String filename;
    1248         if (!item->asString(filename))
    1249             SYNC_FAIL_WITH_PREDEFINED_ERROR(InternalError);
    1250 
    1251         newFileList.append(filename);
     1251        if (!filenames.get(i)->asString(filename))
     1252            SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "The parameter 'filenames' contains a non-string value.");
     1253
     1254        if (!fileContents) {
     1255            newFileList.append(filename);
     1256            continue;
     1257        }
     1258
     1259        String fileData;
     1260        if (!fileContents->get(i)->asString(fileData))
     1261            SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "The parameter 'fileContents' contains a non-string value.");
     1262
     1263        Optional<String> localFilePath = platformGenerateLocalFilePathForRemoteFile(filename, fileData);
     1264        if (!localFilePath)
     1265            SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "The remote file could not be saved to a local temporary directory.");
     1266
     1267        newFileList.append(localFilePath.value());
    12521268    }
    12531269
     
    20492065#endif // !PLATFORM(COCOA) && !USE(CAIRO)
    20502066
     2067#if !PLATFORM(COCOA)
     2068Optional<String> WebAutomationSession::platformGenerateLocalFilePathForRemoteFile(const String&, const String&)
     2069{
     2070    return WTF::nullopt;
     2071}
     2072#endif // !PLATFORM(COCOA)
     2073
    20512074} // namespace WebKit
  • trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h

    r241000 r243340  
    187187    void messageOfCurrentJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle, String* text) override;
    188188    void setUserInputForCurrentJavaScriptPrompt(Inspector::ErrorString&, const String& browsingContextHandle, const String& text) override;
    189     void setFilesToSelectForFileUpload(Inspector::ErrorString&, const String& browsingContextHandle, const JSON::Array& filenames) override;
     189    void setFilesToSelectForFileUpload(Inspector::ErrorString&, const String& browsingContextHandle, const JSON::Array& filenames, const JSON::Array* optionalFileContents) override;
    190190    void getAllCookies(const String& browsingContextHandle, Ref<GetAllCookiesCallback>&&) override;
    191191    void deleteSingleCookie(const String& browsingContextHandle, const String& cookieName, Ref<DeleteSingleCookieCallback>&&) override;
     
    261261#endif // ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS)
    262262
    263     // Get base64 encoded PNG data from a bitmap.
     263    // Get base64-encoded PNG data from a bitmap.
    264264    Optional<String> platformGetBase64EncodedPNGData(const ShareableBitmap::Handle&);
     265
     266    // Save base64-encoded file contents to a local file path and return the path.
     267    // This reuses the basename of the remote file path so that the filename exposed to DOM API remains the same.
     268    Optional<String> platformGenerateLocalFilePathForRemoteFile(const String& remoteFilePath, const String& base64EncodedFileContents);
    265269
    266270#if PLATFORM(COCOA)
  • trunk/Source/WebKit/UIProcess/Automation/cocoa/WebAutomationSessionCocoa.mm

    r239535 r243340  
    11/*
    2  * Copyright (C) 2016, 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2929#if PLATFORM(COCOA)
    3030
     31#import <wtf/FileSystem.h>
     32
    3133#if PLATFORM(IOS_FAMILY)
    3234#include <ImageIO/CGImageDestination.h>
     
    5456
    5557    return String([imageData base64EncodedStringWithOptions:0]);
     58}
     59
     60Optional<String> WebAutomationSession::platformGenerateLocalFilePathForRemoteFile(const String& remoteFilePath, const String& base64EncodedFileContents)
     61{
     62    RetainPtr<NSData> fileContents = adoptNS([[NSData alloc] initWithBase64EncodedString:base64EncodedFileContents options:0]);
     63    if (!fileContents) {
     64        LOG_ERROR("WebAutomationSession: unable to decode base64-encoded file contents.");
     65        return WTF::nullopt;
     66    }
     67
     68    NSString *temporaryDirectory = FileSystem::createTemporaryDirectory(@"WebDriver");
     69    NSURL *remoteFile = [NSURL fileURLWithPath:remoteFilePath isDirectory:NO];
     70    NSString *localFilePath = [temporaryDirectory stringByAppendingPathComponent:remoteFile.lastPathComponent];
     71
     72    NSError *fileWriteError;
     73    [fileContents.get() writeToFile:localFilePath options:NSDataWritingAtomic error:&fileWriteError];
     74    if (fileWriteError) {
     75        LOG_ERROR("WebAutomationSession: Error writing image data to temporary file: %@", fileWriteError);
     76        return WTF::nullopt;
     77    }
     78
     79    return String(localFilePath);
    5680}
    5781
Note: See TracChangeset for help on using the changeset viewer.