Verifying image presence on a webpage using Selenium Webdriver - java

I am trying to verify if the image is present on the webpage or not. Can you suggest me the most feasible code. I am giving the necessary details below.
(Here I am referring to the main product image on left top side in green)
Page URL : http://www.marksandspencer.com/ditsy-floral-tunic/p/p60072079
Also I can send the screenshot if you want. Please send me the email id.
Please suggest at the earliest as I am in need of it.

try to check size of found elements by xpath:
".//*[#class='s7staticimage']/img"
if width is more than 10px -- picture will be shown =)

Here are some of the ways with which you can verify if the image is present,
Checking if the img src contains the file name
Checking if the img webelement size if greater than your desired size
This one is a little outside the scope of webdriver, you need to get the src attribute from the img webelement, then make a GET request to the src to see if you get a 200 OK.
These above verifications will only help ensure that there is an image present on the page, but you cannot verify if the image you want is being displayed unless you do image comparison.
If you want to do image comparisons then take a look at https://github.com/facebookarchive/huxley

Here is the code to verify all images in a webpage - selenium webdriver, TestNG, Java.
public void testAllImages() {
// test webpage - www.yahoo.com
wd.get("https://www.yahoo.com");
//Find total No of images on page and print In console.
List<WebElement> total_images = wd.findElements(By.tagName("img"));
System.out.println("Total Number of images found on page = " + total_images.size());
//for loop to open all images one by one to check response code.
boolean isValid = false;
for (int i = 0; i < total_images.size(); i++) {
String url = total_images.get(i).getAttribute("src");
if (url != null) {
//Call getResponseCode function for each URL to check response code.
isValid = getResponseCode(url);
//Print message based on value of isValid which Is returned by getResponseCode function.
if (isValid) {
System.out.println("Valid image:" + url);
System.out.println("----------XXXX-----------XXXX----------XXXX-----------XXXX----------");
System.out.println();
} else {
System.out.println("Broken image ------> " + url);
System.out.println("----------XXXX-----------XXXX----------XXXX-----------XXXX----------");
System.out.println();
}
} else {
//If <a> tag do not contain href attribute and value then print this message
System.out.println("String null");
System.out.println("----------XXXX-----------XXXX----------XXXX-----------XXXX----------");
System.out.println();
continue;
}
}
}

Related

Selenium message-error and message-success in java

I'm facing a problem with finding an element that does not exist. When I try to login into the application, if it failed login it will show the element -
dr.findElement(By.className("message-error ")).getText();
And after a successful login it will show this:
dr.findElement(By.className("message-success")).getText();
When I run the code and it doesn't find the element, then execution stops with the exception: element is not found
String mes=null;
mes=dr.findElement(By.className("message-success")).getText();
if(mes!=null) {
File out= new File("success.txt");
FileWriter fr =new FileWriter(out,true);
PrintWriter pw=new PrintWriter(fr);
pw.println(mes+"|"+user.get(i)+"|"+pass.get(i));
pw.close();
}
mes=dr.findElement(By.className("message-error")).getText();
if(mes!=null) {
File out= new File("error.txt");
FileWriter fr =new FileWriter(out,true);
PrintWriter pw=new PrintWriter(fr);
pw.println(mes+"|"+user.get(i)+"|"+pass.get(i));
pw.close();
}
The element does not appear.
For example, the success element will not shown until it is successful and the error element will not appear in the CSS until it gets an error.
So how can I tell it if element should exit or come to live or appear do an action?
What is the right thing to do in an if statement if the login is successful? Do this and login fail do this?
Use WebdriverWait to wait for the visibility of success message,
// After valid login
WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement successmessage wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("message-success")));
sucessmessage.getText();
Similarly for error message,
// After invalid login
WebElement errormessage wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("message-error")));
errormessage.getText();
What i think is you have same element but the class getting change as per application behavior. suppose if you are able to login in the application then it show the message element with class having attribute message-success and if it won't allow then error message with class having attribute 'message-error' in the same element.
I've handled the same in below code -
// first get the message element with some other locator or other attribute (don't use class name)
WebElement message = driver.findElement(By.locator);
if(message.getAttribute("class").contains("message-success")){
System.out.println("Success message is " + message.getText())
// write the code to perform further action you want on login success
}else if (message.getAttribute("class").contains("message-error")){
System.out.println("Error message is " + message.getText())
// write the code to perform further action you want on login Fail
}else{
System.out.println("Message is empty" + message.getText())
}
Let me know if you have further queries.
My Choice is to use Webdriver wait. it is the perfect way to find an element.
public WebDriverWait(WebDriver driver,15)
WebElement successmessage = wait.until(ExpectedConditions.visibilityOfallElementLocatedby(By.className("message-success")));
sucessmessage.getText();
visibilityOfallElementLocatedby :
An expectation for checking that all elements present on the web page that match the locator are visible. Visibility means that the elements are not only displayed but also have a height and width that is greater than 0.
The above i wrote is for success Message, similar way try for invalid login.
To use different types of wait, check this doc - https://seleniumhq.github.io/selenium/docs/api/java/allclasses-noframe.html
search Wait in that document.
this is the answer for the question it work with me
try {
WebElement sucmes=dr.findElement(By.xpath("//div[#class='message']"));
String suclogin="login success:";
if(sucmes.getText().contains(suclogin)) {
File suclogin= new File("suclog.txt");
FileWriter suclogr =new FileWriter(suclogin,true);
PrintWriter suclogrw=new PrintWriter(suclogr);
suclogrw.println(sucmes.getText());
suclogrw.close();
}else{
//the other action here
}
}

Upload Local Image With Selenium WebDriver (Java)

I have looked at many answers and only found bits and pieces that worked to end up here, so basically I am using selenium to select the file input on the page, then execute some javascript to make it visible, and then send the file path to the keys.
all of this works but when I submit the form the image is not displayed on the final product, e.g. when I click submit and view my post there is no image
Here's my code:
WebElement imageUpload = driver.findElement(By.xpath(("//*[#id=\"FileInputWrapper\"]/input")));
Thread.sleep(600);
js.executeScript("arguments[0].setAttribute('type', 'file');", imageUpload);
Thread.sleep(600);
imageUpload.sendKeys(computerHome + "/downloads/testImageFolder/testImage.jpg");
Thread.sleep(600);
After Selenium does this, this appears above the submit image button:
This means it received my image but for some reason it also did not?
because when I click submit on the post the image is not visible there are no images.
Any ideas are very appreciated.
Thanks.
Below method will help you too browse the file and select it. Just pass 3 required parameters
Element type
Element locator
File path/resource
Here is the code:
/*------- FileUploading(): This method browse and the upload the selected file -------*/
public static void FileUpload(PropertyType ElementType, string Element, string FilePath)
{
if (ElementType == PropertyType.Id)
{
PropertyCollection.wdriver.FindElement(By.Id(Element)).Click();
}
else if (ElementType == PropertyType.XPath)
{
PropertyCollection.wdriver.FindElement(By.XPath(Element)).Click();
}
Thread.Sleep(3000);
SendKeys.SendWait(FilePath);
Thread.Sleep(3000);
SendKeys.SendWait(#"{Enter}");
Thread.Sleep(3000);
}

Java : Determine if String is an URL(without www or http), take its screenshot

I am working on a Spring-MVC webapplication in which we are trying to get a screenshot of an URL. Currently I am using PhantomJS for that task, but it's too slow(>10seconds). Also, the URL's have to be with http/https and www for detecting that it's an URL. As this is a chat application, there can be simple URL's which users add like helloworld.com. Any help would be nice. Thank you.
Code:
String[] words = message.split(" ");
for( String item : words ){
boolean val = ResourceUtils.isUrl(item);
if(val){
urlIdentifier = calcUrl(item);
break;
}else {
System.out.println("Url false is "+item);
}
}
if(urlIdentifier!=null){
replies.setPreviewIdentifier(urlIdentifier);
input.put("preview_identifier",urlIdentifier);
}
Method to calculate screenshot :
private String calcUrl(String website){
try {
String identifier = String.valueOf(new BigInteger(130, random).toString(32));
String previewLocation = msg + "chatthumbs/" + identifier ;
Process proc = Runtime.getRuntime().exec("phantomjs --ssl-protocol=any " +
"/home/deploy/phantom/rasterizepdf.js " +" "+website+" " +previewLocation);
proc.waitFor();
BufferedImage image = ImageIO.read(new File("/home/akshay/testme.png"));
if(image!=null){
if (image.getWidth() > image.getHeight()) {
image = Scalr.resize(image, Scalr.Mode.FIT_TO_HEIGHT, 250, 250);
} else {
image = Scalr.resize(image, Scalr.Mode.FIT_TO_WIDTH, 250, 250);
}
image = Scalr.crop(image, 250, 250);
ImageIO.write(image, "png", new File(previewLocation));
}
return identifier;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
Any help would be nice. Thank you.
(a) I think the process of taking a screen shot is taking time. Is this code running on the same device as the chat screen? Why not use java.awt.Robot to take the screen shot ? or just save the text why do you need a screen shot?
(b) Is the system too busy/ Use on a SSD to see if faster?
(c) But curious as to the end application, is this part of a web app? How will your code run on the client systems? Or will you java agent be installed on all user systems that monitors the web page and takes screen shots? Then why use a web page, use a java app to chat, and parse the text as typed.
Parsing the text. What if user types/ pastes a long message? Are you parsing everything once or on change? Think of ways to improve that if it seems to be a problem. Ignore if not the immediate issue now.
Also if the msg is too long the parsing can take a lot of time. maybe process after every key press or change event (if paste) keep local js copy of previous text to get diff?

HtmlUnit: opening new page with the same WebClient

I am trying to parsing a website wiht HtmlUnit and Jsoup and i facing this problem.
I have different pages to parse and I stored this links of this pages in a string array.
I want to loop on array's length and parse each page and i proceed in this way.
1) For loop on the length of link's array
2) Opening new webclient
3) Creating new HtmlPage from link with getPage method
4) Parsing and getting some elements
5) Closing webclient
6) go back to 2).
In this way, i'm obtaining what I want, but code it's little bit slow. So i tried to open and close webClient outside the for loop. Like this:
1) Opening new webclient
2) For loop on the length of link's array
3) Creating new HtmlPage from link with getPage method
4) Parsing and getting some elements
5) go back to 2).
6) Closing webclient
It's much more faster but i'm not obtaining same results of previous way.
Is it wrong to use webclient constructor in this way?
EDIT:
Following the code I'm testing:
public static void main(String[] args) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
// TODO Auto-generated method stub
java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(java.util.logging.Level.OFF);
String[] links = {"http://www.oddsportal.com/tennis/china/atp-beijing/murray-andy-dimitrov-grigor-fTdGYm3q/#cs;2;6",
"http://www.oddsportal.com/tennis/china/atp-beijing/murray-andy-dimitrov-grigor-fTdGYm3q/#cs;2;9"};
String bm = null;
String[] odds = new String[2];
//Second way
WebClient webClient = new WebClient(BrowserVersion.CHROME);
System.out.println("Client opened");
for (int i=0; i<links.length; i++) {
HtmlPage page = webClient.getPage(links[i]);
System.out.println("Page loaded");
Document csDoc = Jsoup.parse(page.asXml());
System.out.println("Page parsed");
Element table = csDoc.select("table.table-main.detail-odds.sortable").first();
Elements cols = table.select("td:eq(0)");
if (cols.first().text().trim().contains("bet365.it")) {
bm = cols.first().text().trim();
odds[i]=table.select("tbody > tr.lo").select("td.right.odds").first().text().trim();
}
else {
Elements footTable = csDoc.select("table.table-main.detail-odds.sortable");
Elements footRow = footTable.select("tfoot > tr.aver");
odds[i] = footRow.select("td.right").text().trim();
bm = "AVG";
}
webClient.close();
}
System.out.println(bm +"\t" +odds[0] + "\t" + odds[1]);
}
If i run this code results are right. If i move webClient.close(); outside the for loop results are not correct. In particular odds[0] is equal to odds[1];
Think about WebClient as the replacement of your browser. Creating a new WebClient is like starting a new browser.
If you like to do something equal to open a new tab in your browser, you can use WebClient#openWindow(..). And from the memory point of view it is a good idea to close the window if you are done.
If you are looking for performance, why you re-parse the whole page Jsoup. HtmlUnit retrieves the page, parses the page, creates the whole DOM and runs the javascript on top of this dom before your are getting back the page from your getPage call.
Then you are using HtmlUnit to serialize the Dom tree back to Html and use Jsoup to parse the page again.
HtmlUnit offers many ways to search for elements on a page. I'm suggesting to use this API directly on the page you got.

Convert embedded pictures in database

I have a 'small' problem. In a database documents contain a richtextfield. The richtextfield contains a profile picture of a certain contact. The problem is that this content is not saved as mime and therefore I can not calculate the url of the image.
I'm using a pojo to retrieve data from the person profile and use this in my xpage control to display its contents. I need to build a convert agent which takes the content of the richtextitem and converts it to mime to be able to calculate the url something like
http://host/database.nsf/($users)/D40FE4181F2B86CCC12579AB0047BD22/Photo/M2?OpenElement
Could someone help me with converting the contents of the richtextitem to mime? When I check for embedded objects in the rt field there are none. When I get the content of the field as stream and save it to a new richtext field using the following code. But the new field is not created somehow.
System.out.println("check if document contains a field with name "+fieldName);
if(!doc.hasItem(fieldName)){
throw new PictureConvertException("Could not locate richtextitem with name"+fieldName);
}
RichTextItem pictureField = (RichTextItem) doc.getFirstItem(fieldName);
System.out.println("Its a richtextfield..");
System.out.println("Copy field to backup field");
if(doc.hasItem("old_"+fieldName)){
doc.removeItem("old_"+fieldName);
}
pictureField.copyItemToDocument(doc, "old_"+fieldName);
// Vector embeddedPictures = pictureField.getEmbeddedObjects();
// System.out.println(doc.hasEmbedded());
// System.out.println("Retrieved embedded objects");
// if(embeddedPictures.isEmpty()){
// throw new PictureConvertException("No embedded objects could be found.");
// }
//
// EmbeddedObject photo = (EmbeddedObject) embeddedPictures.get(0);
System.out.println("Create inputstream");
//s.setConvertMime(false);
InputStream iStream = pictureField.getInputStream();
System.out.println("Create notesstream");
Stream nStream = s.createStream();
nStream.setContents(iStream);
System.out.println("Create mime entity");
MIMEEntity mEntity = doc.createMIMEEntity("PictureTest");
MIMEHeader cdheader = mEntity.createHeader("Content-Disposition");
System.out.println("Set header withfilename picture.gif");
cdheader.setHeaderVal("attachment;filename=picture.gif");
System.out.println("Setcontent type header");
MIMEHeader cidheader = mEntity.createHeader("Content-ID");
cidheader.setHeaderVal("picture.gif");
System.out.println("Set content from stream");
mEntity.setContentFromBytes(nStream, "application/gif", mEntity.ENC_IDENTITY_BINARY);
System.out.println("Save document..");
doc.save();
//s.setConvertMime(true);
System.out.println("Done");
// Clean up if we are done..
//doc.removeItem(fieldName);
Its been a little while now and I didn't go down the route of converting existing data to mime. I could not get it to work and after some more research it seemed to be unnecessary. Because the issue is about displaying images bound to a richtextbox I did some research on how to compute the url for an image and I came up with the following lines of code:
function getImageURL(doc:NotesDocument, strRTItem,strFileType){
if(doc!=null && !"".equals(strRTItem)){
var rtItem = doc.getFirstItem(strRTItem);
if(rtItem!=null){
var personelDB = doc.getParentDatabase();
var dbURL = getDBUrl(personelDB);
var imageURL:java.lang.StringBuffer = new java.lang.StringBuffer(dbURL);
if("file".equals(strFileType)){
var embeddedObjects:java.util.Vector = rtItem.getEmbeddedObjects();
if(!embeddedObjects.isEmpty()){
var file:NotesEmbeddedObject = embeddedObjects.get(0);
imageURL.append("(lookupView)\\");
imageURL.append(doc.getUniversalID());
imageURL.append("\\$File\\");
imageURL.append(file.getName());
imageURL.append("?Open");
}
}else{
imageURL.append(doc.getUniversalID());
imageURL.append("/"+strRTItem+"/");
if(rtItem instanceof lotus.domino.local.RichTextItem){
imageURL.append("0.C4?OpenElement");
}else{
imageURL.append("M2?OpenElement");
}
}
return imageURL.toString()
}
}
}
It will check if a given RT field is present. If this is the case it assumes a few things:
If there are files in the rtfield the first file is the picture to display
else it will create a specified url if the item is of type Rt otherwhise it will assume it is a mime entity and will generate another url.
Not sure if this is an answer but I can't seem to add comments yet. Have you verified that there is something in your stream?
if (stream.getBytes() != 0) {
The issue cannot be resolved "ideally" in Java.
1) if you convert to MIME, you screw up the original Notes rich text. MIME allows only for sad approximation of original content; this might or might not matter.
If it matters, it's possible to convert a copy of the original field to MIME used only for display purposes, or scrape it out using DXL and storing separately - however this approach again means an issue of synchronization every time somebody changes the image in the original RT item.
2) computing URL as per OP code in the accepted self-answer is not possible in general as the constant 0.C4 in this example relates to the offset of the image in binary data of the RT item. Meaning any other design of rich text field, manually entered images, created by different version of Notes - all influence the offset.
3) the url can be computed correctly only by using C API that allows to investigate binary data in rich text item. This cannot be done from Java. IMO (without building JNI bridges etc)

Categories

Resources