How to set Safari download location - Selenium WebDriver - java

Trying to set safari (driver) download directory to specific location.
Now it will just download files to default "Downloads" folder.
String currentDirectory = System.getProperty("user.dir");
String downloadFilePath = currentDirectory+"/download/";
Already tried:
dc.setCapability("safari.download.dir", downloadFilePath);
dc.setCapability("browser.download.dir", downloadFilePath);
dc.setCapability("safari.options.dataDir", downloadFilePath); // ("safari.options.dataDir" // this part won't work)
safariOptions.setCapability("safari.options.dataDir", downloadFilePath);
safariPrefs.put("download.deafult_directory", downloadFilePath); // this one I am using for chromedriver (chromePrefs)

Well, you can try to use an HTTP connection to download the file! That way, you can for sure have it saved to the directory specified in your variable.
Most languages have APIs (or libraries) for performing HTTP requests. For example, to accomplish this in Java, you could use URL.openConnection()
String link = linkElement.getAttribute("href");
URL url = new URL(link);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("GET");
Then you can use HttpURLConnection.getInputStream() to write the file contents to your preferred location.
try (InputStream in = httpURLConnection.getInputStream()) {
Files.copy(in, new File("/path/to/file.ext").toPath(),
StandardCopyOption.REPLACE_EXISTING);
}
ONLY IN CASE YOU ARE USING COOKIES:
You can add them to your HTTP connection. If in this case, you must use a password saved on your cookies, this can be very useful.
Set<Cookie> cookies = webDriver.manager().getCookies();
String cookieString = "";
for (Cookie cookie : cookies) {
cookieString += cookie.getName() + "=" + cookie.getValue() + ";";
}
httpURLConnection.addRequestProperty("Cookie", cookieString);

Related

Does URLConnection download the file?

I need to do some verification on a file before downloading it. I need to verify some of the information about it (extension, MIME type and size). I've got something like this:
URL u = new URL("https://test.com/Flight.pdf?some=true&added=8data=7678");
URLConnection uc = u.openConnection();
String type = uc.getContentType();
int length = uc.getContentLength()
String extension = FilenameUtils.getExtension(u.getPath());
Does opening the URL connection and getting the data I need will download the actual file?

How to open URL with anchors in Java?

I would like to add documentation to my project. By clicking on F1, I open the documentation in a certain place (for documentation I have 1 file(index.htm)). However, I can not open the URL with anchor. I have formed the correct URL, but .browse () open the document without anchor(at the beginning).
public void openHtmlDocument() throws IOException, URISyntaxException {
ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
File file = new File(servletContext.getRealPath("/documentation/index.htm"));
URL url = new URL(file.toURI().toURL(), "#_Toc502051959");
Desktop.getDesktop().browse(url.toURI());
}
How can I fix this? The rest of other answers did not actual for me, because users use Windows or Linux.
Formed URI:
file:/D:/app/wildfly-13.0.0.Final/standalone/tmp/vfs/deployment/deployment545477ea955f6f3d/mainUI-1.2.14.0.war-7f1f239336b4e258/documentation/index.htm#_Toc502051959
My browser URL after opening:
This is really a pain. Desktop.browse is not working with anchors as discussed here:
How to launch a file protocol URL with an anchor from Java?
The link gives possible workarounds for windows.
With Linux you may be able to open the url by executing this command:
Runtime.exec("open file:/D:/app/wildfly-13.0.0.Final/standalone/tmp/vfs/deployment/deployment545477ea955f6f3d/mainUI-1.2.14.0.war-7f1f239336b4e258/documentation/index.htm#_Toc502051959");
Solution for my problem, if suddenly someone faces the same problem:
String menuNameNotBlanked = menuName == null ? "" : menuName.replace(" ","_");
String formPathNotBlanked = formPath == null ? "" : formPath.replace(".xhtml","").replace("/","_");
String helpPath = ((ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext()).getRealPath(HELP_FILE_PATH);
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
URL contextURL = new URL(request.getScheme(),request.getServerName(),request.getServerPort(),request.getContextPath());
URL helpURL = new URL(contextURL.toString()+ "/" + HELP_FILE_PATH + AddLeadString(menuNameNotBlanked+formPathNotBlanked,"#"));
RequestContext.getCurrentInstance().execute("window.open('" + helpURL + "')");

Access GoogleCloudStorage using GoogleCloudEndpoints

I'm working on this project in which I'm using a Google-App-Engine backend connected to an Android app via Google-Cloud-Endpoints. For Google-Cloud-Datastore access I'm using Objectify and everything works fine.
Now I decided to add the functionality to upload images to Google-Cloud-Storage but I couldn't find a clear explanation on how to do this using the Google-Cloud-Endpoints setup.
I found the following explanation how to use Google-Cloud-Storage with Google-App-Engine:
https://cloud.google.com/appengine/docs/java/googlecloudstorageclient/app-engine-cloud-storage-sample
but instead of adding it to the Endpoints Api the article writes an additional servlet.
Furthermore I found this example of upload/download for Android:
github.com /thorrism/GoogleCloudExample
Sadly this is using the Google Cloud Storage API for direct access to the Google-Cloud-Storage and you need to add a P12-file to the asset folder, which seems unsecure.
My Google-App-Engine code looks like that:
#Api(
name = "example",
version = "v1",
scopes = { Constants.EMAIL_SCOPE },
clientIds = { Constants.WEB_CLIENT_ID, Constants.ANDROID_CLIENT_ID, Constants.API_EXPLORER_CLIENT_ID },
audiences = {Constants.ANDROID_AUDIENCE},
description = "API for the Example Backend application."
)
public class ExampleApi{
#ApiMethod(name = "doSomething", path = "dosomething", httpMethod = HttpMethod.POST)
public String doSomething(#Named("text") String text){
TestEntity test = new TestEntity(text);
ofy().save().entity(test).now();
return test;
}
After I uploaded it I generated the Endpoints Client Library and imported it into my android project.
Then I'm calling Endpoints from Android like explained here:
https://cloud.google.com/appengine/docs/java/endpoints/calling-from-android#creating_the_service_object
public static com.appspot.******.example.Example buildServiceHandler(Context context, String email) {
GoogleAccountCredential credential = GoogleAccountCredential.usingAudience(
context, AppConstants.AUDIENCE);
credential.setSelectedAccountName(email);
com.appspot.******.example.Example.Builder builder = new com.appspot.******.example.Example.Builder(
AppConstants.HTTP_TRANSPORT,
AppConstants.JSON_FACTORY, null);
builder.setApplicationName("example-server");
return builder.build();
}
sApiServiceHandler = buildServiceHandlerWithAuth(context,email);
And each Api-Method I call like this:
com.appspot.******.example.Example.DoSomething doSomething = sApiServiceHandler.doSomething(someString);
doSomething.execute();
All of this works fine, but only for storing/receiving Datastore Entities. How would I go about uploading/downloading files to Google Cloud Storage using the Google Cloud Endpoints setup?
Is it somehow possible to send a POST with my image data via Endpoints to the UploadServlet using the already build ServiceHandler ?
Is it possible to call a servlet from an Endpoints Method? How am I supposed to send the Post to the Servlet and how would I go about the authentication?
Any help or advice would be greatly appreciated!
There are different ways to do this, but the most recommended way is to use Signed URLs, so that your Android app can upload the file securely to Google Cloud Storage directly, without going through your Endpoints backend. The basic process is:
1) Create an Endpoints method that creates a new signed URL and returns it to the Android client. Signing the URL on the server still requires a P12 key but is stored on App Engine, not on the client, so is secure. Try to use a short expiration for the URL, for example no more than 5 minutes.
2) Have the Android client upload the file directly to the signed URL, as you would doing a normal HTTP PUT to the Cloud Storage XML API to upload a file (resumable uploads with the JSON API are also supported, but not covered here).
Your Endpoints method might look like this:
#ApiMethod(name = "getUploadUrl", path = "getuploadurl", httpMethod = HttpMethod.GET)
public MyApiResponse getUploadUrl(#Named("fileName") String fileName
#Named("contentType" String contentType)
{
String stringToSign
= "PUT\n" + contentType
+ "\n" + EXPIRATION_TIMESTAMP_EPOCH_SECONDS + "\n"
+ YOUR_GCS_BUCKET + "/" + fileName;
// Load P12 key
FileInputStream fileInputStream = new FileInputStream(PATH_TO_P12_KEY);
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(fileInputStream, password);
PrivateKey key = keyStore.getKey(privatekey", YOUR_P12_KEY_PASSWORD);
// Get signature
Signature signer = Signature.getInstance("SHA256withRSA");
signer.initSign(key);
signer.update(stringToSign.getBytes("UTF-8"));
byte[] rawSignature = signer.sign();
String signature = new String(Base64.encodeBase64(rawSignature, false), "UTF-8");
// Construct signed url
String url
= "http://storage.googleapis.com/" + YOUR_GCS_BUCKET + fileName
+ "?GoogleAccessId=" + P12_KEY_SERVICE_ACCOUNT_CLIENT_ID
+ "&Expires=" + EXPIRATION_TIMESTAMP_EPOCH_SECONDS
+ "&Signature=" + URLEncoder.encode(signature, "UTF-8");
// Endpoints doesn't let you return 'String' directly
MyApiResponse response = new MyApiResponse();
response.setString(url);
return response;
}
On the Android side, you might use the method like this:
// Get the upload URL from the API
getUploadUrl = sApiServiceHandler.getUploadUrl(fileName, contentType);
MyApiResponse response = getUploadUrl.execute();
String uploadUrl = response.getString();
// Open connection to GCS
URL url = new URL(uploadUrl);
HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
httpConnection.setDoOutput(true);
httpConnection.setRequestMethod("PUT");
httpConnection.setRequestProperty("Content-Type", contentType);
// Write file data
OutputStreamWriter out = new OutputStreamWriter(httpConnection.getOutputStream());
out.write(fileData);
out.flush();
// Get response, check status code etc.
InputStreamReader in = new InputStreamReader(httpConnection.getInputStream());
// ...
(Disclaimer: I'm just typing code freely into a text editor but not actually testing it, but it should be enough to give you a general idea.)

URL wont open file:\C filepath in Java

I need to open a filename using a URL(java.net.URL) as below:
file:/C:/RAdev/Basic/src/test/resources/xml Data/test
dir/app-config-seed-data.xml
I've the following java code to read
fileURL = new File(filePath).toURI().toURL();
is = fileURL.openStream();
Since windows can access file:\, even URL should be able to open the same.
Workaround used for now:
public static final String FILE_URL_PREFIX = "file:";
if (filePath.contains(FILE_URL_PREFIX)) {
filePath = filePath.replaceAll("file:/", "");
System.out.println("Modified filepath - " + filePath);
}
fileURL = new File(filePath).toURI().toURL();
is = fileURL.openStream();
Is the above workaround needed, please let me know if there is another way to reap the benefits of URL accessing. I'm new to URL/URI in java, help is really appreciated.
Thanks.
file:/C:/ is not a valid file url. Try starting your URLs with file://C:/.
Additionally, the File(String) constructor does not take a URL, it takes a local file path. If you have a URL as a string that you want to parse, use the URL(String) constructor:
URL fileURL = new URL("file://C:/RAdev/Basic/src/test/resources/xml Data/test dir/app-config-seed-data.xml");
is = fileURL.openStream();
Adding the below implementation on top of Darth Android suggestion worked:
URL url = new URL(filePath);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(),
url.getPort(), url.getPath(), url.getQuery(),
url.getRef());
URL fileURL = uri.toURL();
InputStream is = fileURL.openStream();

Java Dropbox API get public share link after uploading file

The following uploads my file to the specified path in dropbox:
DbxEntry.File uploadedFile = client.uploadFile("/" + id + "/name" + ".png",
DbxWriteMode.add(), tile.length(), inputStream);
System.out.println("Uploaded: " + uploadedFile.toString());
However how can i retrieve the Public Share URL after it is uploaded? I can't find any documentation.
Found the right API method:
DbxClient = new DbxClient(config, accessToken);
client.createShareableUrl(path)
Couldn't get any easier...
DbxClient = new DbxClient(config, accessToken);
This call will provide you with a sharable preview Url.
client.createShareableUrl(path);
This call will provide a direct URL. The only catch is the URL will expire.
client.createTemporaryDirectUrl(path);

Categories