Fetching image from Dropbox - dropbox

I'm fetching images from Dropbox using following Java code:
private void downloadFile(#NonNull final String inPath, #NonNull final OutputStream outputStream) throws IOException, DbxException {
mClient.files().downloadBuilder(inPath).download(outputStream);
}
This code works correctly! However, we need to wait for entire JPG to download before it can be shown.
However, is it possible to display partial images as soon as they are fetched using Dropbox?
using Dropbox version 3.0.3

Related

Selenium GeckoDriver failing with blank page

I'm getting a blank page when trying to verify the driver url. I have this set up in debug logging mode. This is the FirefoxWebDriver.
UPDATE: If I take out all webdriver options then the tests work on a server but do not work in a Docker container.
FINAL UPDATE: Switched over to Chrome and found success, but with some important caveats.
[TestMethod]
public void NavigatesToContainerSite()
{
WebDriverWait webDriverWait = new WebDriverWait(_driver, TimeSpan.FromSeconds(30));
_driver.Navigate().GoToUrl("http://www.example.com:8083/");
string url = _driver.Url;
Assert.AreEqual("http://www.example.com:8083/", url);
}
[ClassInitialize]
public static void SetupOnce(TestContext context)
{
_options = new FirefoxOptions();
Proxy p = new Proxy();
p.SocksProxy = proxy url;
p.SocksVersion = 5;
p.Kind = ProxyKind.Manual;
_options.Proxy = p;
_options.PageLoadStrategy = PageLoadStrategy.None;
_options.LogLevel = FirefoxDriverLogLevel.Debug;
_options.AddArguments("--no-sandbox", "--disable-software-rasterizer","--headless" ,"--whitelisted-ips=\"\"",
"--disable-infobars","--disable-gpu","--disable-dev-shm-usage","--disable-extensions");
_driver = new FirefoxDriver(_options);
}
Here is the logging aspect of the request. If I just create a passing test that navigates to the url it seems to work but when I try to get something off the page (url, page elements) it throws exception.
Question: does the 200 OK indicate the driver.navigate succeeded or does it just mean the request for the webdriver session succeeded?
I just put the example.com url in this code example to hide my real url.
"1662816403483\twebdriver::server\tDEBUG\t-> POST /session/b29b42e9-cef5-4ef3-a281-8aafb21ea8cc/url {\"url\":\"http://www.example.com:8083/?username=owen.charles\"}",
"1662816403484\tMarionette\tDEBUG\t0 -> [0,2,\"WebDriver:Navigate\",{\"url\":\"http://www.example.com:8083/"}]",
"1662816403487\tMarionette\tDEBUG\t0 <- [1,2,null,{\"value\":null}]",
"1662816403487\twebdriver::server\tDEBUG\t<- 200 OK {\"value\":null}",
"1662816403541\twebdriver::server\tDEBUG\t-> POST /session/b29b42e9-cef5-4ef3-a281-8aafb21ea8cc/url {\"url\":\"http://www.example.com:8083/"}",
"1662816403542\tMarionette\tDEBUG\t0 -> [0,3,\"WebDriver:Navigate\",{\"url\":\"http://www.example.com:8083/"}]",
"1662816403543\tMarionette\tDEBUG\t0 <- [1,3,null,{\"value\":null}]",
"1662816403543\twebdriver::server\tDEBUG\t<- 200 OK {\"value\":null}",
"1662816403580\twebdriver::server\tDEBUG\t-> GET /session/b29b42e9-cef5-4ef3-a281-8aafb21ea8cc/url ",
"1662816403581\tMarionette\tDEBUG\t0 -> [0,4,\"WebDriver:GetCurrentURL\",{}]",
"1662816403581\tMarionette\tDEBUG\t0 <- [1,4,null,{\"value\":\"about:blank\"}]",
"1662816403581\twebdriver::server\tDEBUG\t<- 200 OK {\"value\":\"about:blank\"}",
"1662816403657\twebdriver::server\tDEBUG\t-> DELETE /session/b29b42e9-cef5-4ef3-a281-8aafb21ea8cc ",
"1662816403658\tMarionette\tDEBUG\t0 -> [0,5,\"Marionette:Quit\",{\"flags\":[\"eForceQuit\"]}]",
"1662816403658\tMarionette\tINFO\tStopped listening on port 49197",
This method doesn't produce an error:
[TestMethod]
public void NavigatesToContainerSite()
{
WebDriverWait webDriverWait = new WebDriverWait(_driver, TimeSpan.FromSeconds(30));
_driver.Navigate().GoToUrl("http://www.example.com:8083");
Assert.AreEqual("one", "one");
}
No one answered this but I did come up with a solution so I will just post it here. I had enough issues with the GeckoWebDriver that I switched to ChromeWebDriver. But the solution I arrived at may resolve the Gecko issue as well.
Steps I took:
Downloaded Chrome, major version 105
Incorporated ChromeWebDriver, major version 105 (these two have to match!)
Set two arguments when I instantiate the ChromeWebDriver in code
ChromeOptions options = new ChromeOptions();
options.AddArguments("--no-sandbox","--headless");
return new ChromeDriver(options);
Then it came to changes in the dockerfile for deploying this in a container. Because I have a Windows Docker host, I must deploy to a Windows container. I found out that Chrome requires about four or five fonts, and their various iterations, for its default installation to work. The Windows container only has one font in the installation. If you pull up Chrome settings, you'll probably see these fonts. One is for serif fonts, another sans-serif, etc. These fonts are:
arial.ttf
arialbd.ttf
arialbi.ttf
ariali.ttf
arialn.ttf
arialnb.ttf
arialni.ttf
ariblk.ttf
consola.ttf
consolab.ttf
consolaz.ttf
times.ttf
timesbi.ttf
timesi.ttf
I had to manually install these fonts into the windowsservercore image of Windows.
The resulting dockerfile looks like this:
FROM mcr.microsoft.com/dotnet/sdk:6.0-windowsservercore-ltsc2019
COPY ./test /test
WORKDIR /test
SHELL ["powershell"]
RUN "Add-WindowsFeature Web-WebSockets"
RUN Fonts/Add-Font.ps1 Fonts/Fonts
RUN ["msiexec","/i","chrome.msi","/qn"]
ENTRYPOINT ["dotnet", "test", "--logger:trx"]
In addition, I had to allocate 2g of shared memory in my Docker run statement.
docker run --shm-size="2g"
I found that the Selenium tests kick off about 5 instances of the browser and the web driver, sometimes taking up 600 MB of RAM. This will disappear if you use the driver.quit method after test is complete.
And voila, everything green.

How to open a html file available in local machine in selenium grid node

I have a html file in my local machine. When running my selenium-java code locally through eclipse, I can access the html file through the code mentioned below -
File file = new File(url);
driver.get("file:///" + file.getAbsolutePath());
If I run the code through selenium grid, registered node doesn't pick up the html file path to be opened in chrome since the absolute path points to the local machine.
Is there any solution available to open the locally available html file through selenium grid-node?
You should use a LocalFileDetector.
import org.openqa.selenium.remote.LocalFileDetector
import org.openqa.selenium.remote.RemoteWebDriver
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), DesiredCapabilities.firefox());
driver.setFileDetector(new LocalFileDetector())
Your upload should now work.
There are basically two ways in which you can get this done. I will list out both the approaches. Please feel free to pick and choose whichever works for you.
Using custom node servlet
You need to follow the below steps:
Create a new custom servlet, using which you can upload a file using a HTTP POST method.
It could look something like below [ This code is borrowed from a journaldev post here and being included here only for the sake of completeness] You may need to tweak the code before use and not necessarily use it as is. The current code returns a html response, but you may need to change it so that it returns a JSON response which contains the actual path where the file was uploaded to. This path is what you will use in your driver.get() call.
package com.journaldev.servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadDownloadFileServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private ServletFileUpload uploader = null;
#Override
public void init() throws ServletException{
DiskFileItemFactory fileFactory = new DiskFileItemFactory();
File filesDir = (File) getServletContext().getAttribute("FILES_DIR_FILE");
fileFactory.setRepository(filesDir);
this.uploader = new ServletFileUpload(fileFactory);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileName = request.getParameter("fileName");
if(fileName == null || fileName.equals("")){
throw new ServletException("File Name can't be null or empty");
}
File file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileName);
if(!file.exists()){
throw new ServletException("File doesn't exists on server.");
}
System.out.println("File location on server::"+file.getAbsolutePath());
ServletContext ctx = getServletContext();
InputStream fis = new FileInputStream(file);
String mimeType = ctx.getMimeType(file.getAbsolutePath());
response.setContentType(mimeType != null? mimeType:"application/octet-stream");
response.setContentLength((int) file.length());
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
ServletOutputStream os = response.getOutputStream();
byte[] bufferData = new byte[1024];
int read=0;
while((read = fis.read(bufferData))!= -1){
os.write(bufferData, 0, read);
}
os.flush();
os.close();
fis.close();
System.out.println("File downloaded at client successfully");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if(!ServletFileUpload.isMultipartContent(request)){
throw new ServletException("Content type is not multipart/form-data");
}
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.write("<html><head></head><body>");
try {
List<FileItem> fileItemsList = uploader.parseRequest(request);
Iterator<FileItem> fileItemsIterator = fileItemsList.iterator();
while(fileItemsIterator.hasNext()){
FileItem fileItem = fileItemsIterator.next();
System.out.println("FieldName="+fileItem.getFieldName());
System.out.println("FileName="+fileItem.getName());
System.out.println("ContentType="+fileItem.getContentType());
System.out.println("Size in bytes="+fileItem.getSize());
File file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileItem.getName());
System.out.println("Absolute Path at server="+file.getAbsolutePath());
fileItem.write(file);
out.write("File "+fileItem.getName()+ " uploaded successfully.");
out.write("<br>");
out.write("Download "+fileItem.getName()+"");
}
} catch (FileUploadException e) {
out.write("Exception in uploading file.");
} catch (Exception e) {
out.write("Exception in uploading file.");
}
out.write("</body></html>");
}
}
Create a sample project, which includes a dependency on the selenium libraries and which contains the servlet built in step (1) and create a jar out of it. For instructions on how to do all of this, you can refer to my blog post here (or) to the official selenium documentation here.
Start the node, along with the -servlets parameter so that your newly created node servlet, gets injected into the node and is available via http://<Node_IP_Address>:<Node_Port>/extra/UploadDownloadFileServlet (since our sample servlet's name was UploadDownloadFileServlet)
Now in your test code, you can create a new RemoteWebDriver instance as always.
You now need to upload your html file to the remote node where the new session was created. For doing that, you need to know the IP of the node where your test ran. So you make use of a library such as talk2grid (I built this library) or leverage the approach of determining this information on your own by referring to my blog here
Once you have the IP and port, you now trigger a HTTP POST to the servlet you created earlier by hitting the endpoint http://<Node_IP_Address>:<Node_Port>/extra/UploadDownloadFileServlet and get back the path to where it was uploaded in the response.
Now use the path that was returned in step (6) in your driver.get() call (don't forget to include the file:/// protocol)
That should do.
Using Javascript
In this approach, you basically start off by loading a blank page (for e.g., driver.get("about:blank"); and then make use of Javascript to start dynamically creating your web page via document.createElement() call (Refer to this article for more information ) and create the entire page. You can now start interacting with the page.
Approach (1) would be useful only when you are working with a grid environment wherein you are allowed to add servlets etc and access its IP and port.
Approach (2) will work in all use cases including third party remote execution environment providers such as SauceLabs or BrowserStack (In case you use them as well)

Reading image contents using selenium and java

I want to read content of image using selenium and asprise jars and added below jar files in my project :
aocr.jar
AspriseOCR
and below is my code :
BufferedImage image = ImageIO.read(new File("C:\\Users\\siddhesh.kalgaonkar\\Desktop\\love.jpg"));
String imageText = new OCR().recognizeCharacters((RenderedImage)image);
System.out.println("Text From Image : \n"+ imageText);
System.out.println("Length of total text : \n"+ imageText.length());
but its giving below error :
java.lang.UnsatisfiedLinkError: no AspriseOCR in java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at com.asprise.util.ocr.OCR.loadLibrary(OCR.java:247)
at com.asprise.util.ocr.OCR.<init>(OCR.java:56)
at com.image.selenium.ImageVerification.start(ImageVerification.java:52)
I also tried setting java.library.path using this link but of no use. Please help anyone.
I got an answer to my own question. We can now do it with the help of below information:
Add latest aocr.jar to your project. Download it from
this link.
Include pom.xml file in your project for maven dependencies and add this dependency :
<dependency>
<groupId>com.asprise.ocr</groupId>
<artifactId>java-ocr-api</artifactId>
<version>[15,)</version>
</dependency>
Write below code in your java file :
public class ImageVerification
{
WebDriver driver;
#Test
public void start() throws IOException {
Ocr ocr = new Ocr(); // create a new OCR engine
ocr.startEngine("eng", Ocr.SPEED_FASTEST); // English
String s = ocr.recognize(new File[] { new File("C:\\Users\\siddhesh.kalgaonkar\\Desktop\\love.jpg") },
Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
System.out.println(s);
ocr.stopEngine();
}
For more details refer this link
Enjoy :)
NOTE: It works only for images with plain text.It doesn't work for images with data in graph format or pie chart or trend chart

Upload File on selenium node (grid environment) , where in upload button is not of input(type='file')

I do have a page , where import button looks like this .
Dom Structure of above import button is as below
<button ngf-select="" ng-model="$parent.enduserMashups.files" class="btn btn-default text-center ng-pristine ng-untouched ng-valid ng-empty">
<i class="icon-import-data"></i>
<span>Import</span></button>
I have written selenium upload utility as below , which works fine in case of NON-GRID environment (local machine)
public void uploadFile(String filePath)
{
// Setting up clipBoard location
StringSelection ss = new StringSelection(filePath);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
// Using Robot class to upload file
Robot robot;
try
{
robot = new Robot();
try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
// Press Enter
robot.keyPress(KeyEvent.VK_ENTER);
// Release Enter
robot.keyRelease(KeyEvent.VK_ENTER);
// Press CTRL+V
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
// Release CTRL+V
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_V);
try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
};
// Press Enter
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
} catch (AWTException e)
{
e.printStackTrace();
}
}
In case of running above code on selenium grid-node environment , 'import' button gets clicked on node browser instance and here it doesn't find file(obviously), as it is saved on another machine from where testcase is running .
Googling a lot , I found some solutions which states that in case of having button , we can use webdriver.sendKeys(file) method , which sends file to selenium node directly , however that is applicable in case of tag only .
What about in case of NOT having element ?
Here's what you can do to solve your issue.
You need to build a custom servlet which has a POST/GET method defined and which can be used to trigger a file upload. ( See here for an example). You need to also make sure that this servlet will return back the absolute file path of where the file was saved after it was accepted.
You now inject the newly built custom servlet into the Grid node ( See here to learn how to do it )
Similar to (1) and (2) you build another servlet with a GET/POST action which when invoked can internally call your uploadFile() method. [ You will basically pass the filepath that you obtain from invoking the servlet explained in (1)
You refer to this blog post of mine to learn how to find out where did the Grid route your tests to and using the mechanism I have explained you retrieve the IP and port of the node to which your test was routed to.
Using the IP and Port number obtained from (4) you first invoke the Upload file servlet to first upload your file to the remote machine on which the node is running and get back the saved file's absolute file path from the servlet.
You now invoke your other servlet which contains the uploadFile() method and driven by the ROBOT APIs by passing the absolute file path from (5) and have it perform the upload action using ROBOT on the remote host.
That should do the trick.

How to handle favicon.ico in headless selenium with xvfb

I have the various scenarios of selenium test script which is properly running on selenium web driver with firefox browser. when i running them in headless mode some of scenarios are running but some of them are not running some time but most of time it fails and throw the error like
onhandlernotfound/favicon.ico
and
pagenotfound/favicon.ico[onhandlernotfound/favicon.ico]
the screenshot attached - first and second.
Give me the solution as soon as possible
my test case failed and get the error that element is not currently visible so may not be interacted with
element is not currently visible so may not be interacted with
You can try to get favicon internet-path and try to download it(externally, not via the selenium).
If favicon will be not accessible -- there will be no ability to download. If its is accessible -- its will be shown in any of browser (in case of enabled images) =)
Maybe this is not the best way, but this will work.
As you didnt write your language, I can give you code to download image for c#:
string webPath = ""; /*favicon internet path*/
if (webPath != string.Empty)
{
try
{
System.Net.WebRequest request = System.Net.WebRequest.Create(webPath);
System.Net.WebResponse response = request.GetResponse();
System.IO.Stream responseStream = response.GetResponseStream();
Bitmap bitmapImg = new Bitmap(responseStream);
return bitmapImg;
}
catch (System.Net.WebException)
{
}
}