Reading image contents using selenium and java - selenium

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

Related

Running Selenium-java automation inside Gitpod

New to the platform & test automation & selenium. I got introduced to Gitpod while attempting https://www.lambdatest.com/certifications/.
for starters I'm stuck trying to run the below simple code snippet in side Gitpod
package project.maven.selenium;
import org.openqa.selenium.WebDriver;
import io.github.bonigarcia.wdm.WebDriverManager;
public class WebDriverManagerDemo {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = WebDriverManager.chromedriver().create();
// Navigate to the demoqa website
driver.get("https://www.lambdatest.com/selenium-playground/checkbox-demo");
Thread.sleep(3000);
driver.quit();
}
}
Couldn't find a way pass the error below,
Exception in thread "main" io.github.bonigarcia.wdm.config.WebDriverManagerException: There was an error creating WebDriver object for Chrome
at io.github.bonigarcia.wdm.WebDriverManager.instantiateDriver(WebDriverManager.java:1775)
at io.github.bonigarcia.wdm.WebDriverManager.create(WebDriverManager.java:425)
at project.maven.selenium.WebDriverManagerDemo.main(WebDriverManagerDemo.java:9)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
can someone point out what I'm doing wrong please?
Researched hours but Selenium on Gitpod is not much of a topic, read the getting started guide with Gitpod too, to find a resolution to my problem but no luck before posting here.

Log custom text to Cucumber JVM or Extent Reports

Please guide me in logging custom text which are there inside a method into Cucumber JVM (Masterthought) or Extent Reports.
I am using Cucumber Junit BDD Framework and have the below dependencies in my POM file -
<!-- Cucumber JVM Report -->
<dependency>
<groupId>net.masterthought</groupId>
<artifactId>cucumber-reporting</artifactId>
<version>5.1.0</version>
</dependency>
<!-- Extent Report -->
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports-cucumber4-adapter</artifactId>
<version>1.2.1</version>
</dependency>
And my Runner file is as below -
#CucumberOptions(
tags = {"#SANITY,#REGRESSION,#E2E"},
features = "src/test/resources/cta-features/features/",
plugin = {
"json:target/cucumber-reports/cucumber.json", "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:",
"pretty"
},
glue = {
"e2e.steps",
"e2e.hooks"
})
#RunWith(Cucumber.class)
public class TestRunner {
#BeforeClass
public static void init() throws Exception {
}
#AfterClass
public static void generateReport() throws Exception {
File reportOutputDirectory = new File("target");
List<String> jsonFiles = new ArrayList<>();
jsonFiles.add("target/cucumber-reports/cucumber.json");
String buildNumber = "1";
String projectName = "Project";
Configuration configuration = new Configuration(reportOutputDirectory, projectName);
// optional configuration - check javadoc for details
configuration.addPresentationModes(PresentationMode.RUN_WITH_JENKINS);
// do not make scenario failed when step has status SKIPPED
configuration.setNotFailingStatuses(Collections.singleton(Status.SKIPPED));
configuration.setBuildNumber(buildNumber);
// addidtional metadata presented on main page
configuration.addClassifications("Platform", "Windows");
configuration.addClassifications("Browser", "Chrome");
configuration.addClassifications("Branch", "release/1.0");
ReportBuilder reportBuilder = new ReportBuilder(jsonFiles, configuration);
Reportable result = reportBuilder.generateReports();
// and here validate 'result' to decide what to do if report has failed
}
I am able to successfully generate report in both master thought and Extent which will contain Feature level statements and Step Level statements (I have used scenario.write for this). But my client wants one more level deeper where he can get info as to which link or button was clicked etc which i am currently publishing to my console using Log4j
Example :
Log.info("Random Button or Link was clicked and Operation is successful")
My clients wants this to be integrated into the report (In Either Masterthought or Extent). Is there a way to do this ?
Extent cucumber adapter provides addtestlog to log additional steps .
Please check below example -
ExtentCucumberAdapter.addAddTestStepLog(BTN.getText());
As per your Pom.xml file you are using adapter 4 if you cannot find method try to switch into cucumber adapter 6 and other essential dependency of cucumber 6. That will surely help you :)

How to create a cucumber-java custom formatter to get cucumber tags

I have a cucumber project and I want to get al the tags in the project to be able to choose them as parameters.
I found this question where cucumber had an option to get the tags but I found that doesn't work anymore, then I found this other question where I found I need a custom formatter to get my tags, but it is for ruby, and I need it for Java, so then I found this article on how to create a custom formatter, but I found that this worked for the cukes version and I'm using the io one.
So I searched inside the cucumber packages and created a custom formatter from a copy of the JSONFormatter inside the package cucumber.runtime.formatter, here is my code:
import cucumber.api.TestCase;
import cucumber.api.event.*;
import cucumber.api.formatter.Formatter;
import cucumber.api.formatter.NiceAppendable;
import gherkin.deps.com.google.gson.Gson;
import gherkin.deps.com.google.gson.GsonBuilder;
import gherkin.pickles.PickleTag;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class TagsFormatter implements Formatter {
private String currentFeatureFile;
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private final NiceAppendable out;
private List<String> tags = new ArrayList<>();
private EventHandler<TestCaseStarted> caseStartedHandler = this::handleTestCaseStarted;
private EventHandler<TestRunFinished> runFinishedHandler = event -> finishReport();
public TagsFormatter(Appendable out) {
this.out = new NiceAppendable(out);
}
#Override
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestCaseStarted.class, caseStartedHandler);
publisher.registerHandlerFor(TestRunFinished.class, runFinishedHandler);
}
private void handleTestCaseStarted(TestCaseStarted event) {
if (currentFeatureFile == null || !currentFeatureFile.equals(event.testCase.getUri())) {
currentFeatureFile = event.testCase.getUri();
collectTags(event.testCase);
}
}
private void finishReport() {
out.append(gson.toJson(tags));
out.close();
}
private void collectTags(TestCase testCase) {
testCase.getTags();
tags.addAll(testCase.getTags()
.stream()
.map(PickleTag::getName)
.collect(Collectors.toList()));
}
}
I copied the libraries I need to run cucumber in a lib folder inside my project and tried running it using my formatter like this:
java -cp .\lib\cucumber-core-2.4.0.jar;.\lib\gherkin-5.0.0.jar;.\lib\cucumber-java-2.4.0.jar;.\lib\cucumber-jvm-deps-1.0.6.jar cucumber.api.cli.Main -p "com.myproject.formatters.TagsFormatter:tags.txt"
But Im getting a class not found exception:
λ java -cp .\lib\cucumber-core-2.4.0.jar;.\lib\gherkin-5.0.0.jar;.\lib\cucumber-java-2.4.0.jar;.\lib\cucumber-jvm-deps-1.0.6.jar cucumber.api.cli.Main -p "com.myproject.formatters.TagsFormatter:tags.txt"
Exception in thread "main" cucumber.runtime.CucumberException: Couldn't load plugin class: com.myproject.formatters.TagsFormatter
at cucumber.runtime.formatter.PluginFactory.loadClass(PluginFactory.java:181)
at cucumber.runtime.formatter.PluginFactory.pluginClass(PluginFactory.java:166)
at cucumber.runtime.formatter.PluginFactory.getPluginClass(PluginFactory.java:223)
at cucumber.runtime.formatter.PluginFactory.isFormatterName(PluginFactory.java:201)
at cucumber.runtime.RuntimeOptions$ParsedPluginData.addPluginName(RuntimeOptions.java:471)
at cucumber.runtime.RuntimeOptions.parse(RuntimeOptions.java:157)
at cucumber.runtime.RuntimeOptions.<init>(RuntimeOptions.java:115)
at cucumber.runtime.RuntimeOptions.<init>(RuntimeOptions.java:108)
at cucumber.runtime.RuntimeOptions.<init>(RuntimeOptions.java:100)
at cucumber.api.cli.Main.run(Main.java:31)
at cucumber.api.cli.Main.main(Main.java:18)
Caused by: java.lang.ClassNotFoundException: com.myproject.formatters.TagsFormatter
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at cucumber.runtime.formatter.PluginFactory.loadClass(PluginFactory.java:174)
... 10 more
So, how can I create this formatter in a way it is recognized? or at least get the tags list from cucumber from console?
Thanks
By just eyeballing your code, I don't think there is anything wrong with it. However your command does not appear to include a compiled version of the TagsFormatter on the class path.
If your compiled sources are in .\bin\ make sure to include that folder ie:
java -cp .\lib\cucumber-core-2.4.0.jar;.\lib\gherkin-5.0.0.jar;.\lib\cucumber-java-2.4.0.jar;.\lib\cucumber-jvm-deps-1.0.6.jar;.\bin\* cucumber.api.cli.Main -p "com.myproject.formatters.TagsFormatter:tags.txt"

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)

PDF reader not working

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.nio.file.Files;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.itextpdf.text.pdf.parser.SimpleTextExtractionStrategy;
import com.itextpdf.text.pdf.parser.TextExtractionStrategy;
`
public class Test{
public static void main(String []args) throws IOException
{
String pdf= "c:\\sample.pdf";
PdfReader reader = new PdfReader(pdf);
}
}
it not working
like it should i am running windows
need help please help i tried a lot of things but still getting the same message
here is the error message
this is the output i get when i tried ur code
File Exists: true
Exception in thread "main" java.lang.NoClassDefFoundError:
org/bouncycastle/asn1/ASN1Encodable
at com.itextpdf.text.pdf.PdfEncryption.<init>(PdfEncryption.java:148)
at com.itextpdf.text.pdf.PdfReader.readDecryptedDocObj(PdfReader.java:1024)
at com.itextpdf.text.pdf.PdfReader.readDocObj(PdfReader.java:1430)
at com.itextpdf.text.pdf.PdfReader.readPdf(PdfReader.java:732)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:181)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:219)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:207)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:197)
at pdfconverter.Test.main(Test.java:37)
Caused by: java.lang.ClassNotFoundException:
org.bouncycastle.asn1.ASN1Encodable
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 9 more
The code looks good to me. Perhaps more information on the error you are having? For instance, it could be a classpath error - something like the itextpdf classes not being located...
In case it helps as a baseline - the following code works for me. I removed the extraneous includes, though they won't hurt to leave them in.
import java.io.File;
import com.itextpdf.text.pdf.PdfReader;
public class Test {
public static void main(String[] args) {
String pdf= "C:\\Java-Design-Patterns.pdf";
try {
System.out.println("File Exists: "+new File(pdf).exists());
PdfReader reader = new PdfReader(pdf);
int count = reader.getNumberOfPages();
System.out.println("PDF has "+count+" pages.");
} catch (Exception e) {
System.out.println("Failed to open PDF ["+pdf+"]: "+e);
e.printStackTrace();
}
}
}
The output is:
File Exists: true
PDF has 183 pages.
The itext jar I used is: itextpdf-5.5.12.jar (included via maven).
The pdf I used (courtesy of google: java design patterns pdf) is here: http://enos.itcollege.ee/~jpoial/java/naited/Java-Design-Patterns.pdf
I haven't read it yet, but the first page looks good ;)
That said, itextpdf is quite awesome.
java.lang.NoClassDefFoundError: org/bouncycastle/asn1/ASN1Encodable
clearly indicates the issue: Bouncy Castle is missing! (Or at least the required version is missing.)
Bouncy Castle is a library used by iText for encryption, decryption, signing, and signature verification, here their web representation.
Thus, add the Bouncy Castle libraries to your class path. Please be aware, though, that the BC version required depends on the iText version in question. The maven link you provided for your itext7 version indicates that BC 1.49 is required.