25

Can someone please help!

How can I highlight all web elements in following class during test execution in WebDriver? With Selenium RC, it was quite straight forward but with WebDriver I am struggling.

I would be grateful if someone can please provide me with some code that I can try, also where would that code fit into the class below — sorry my Java skills aren't all that great.

package hisScripts;
import java.util.concurrent.TimeUnit;
import org.testng.annotations.*;
import org.testng.Assert;
import static org.testng.Assert.fail;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.interactions.Actions;


public class R_LHAS_Only_Account_Verification extends HIS_Login_Logout{
    public WebDriver driver;
    public String baseUrl;
    public int exeMonth;
    private StringBuffer verificationErrors = new StringBuffer();

    @BeforeClass
    @Parameters ({"browser1", "url", "executionMonth"})
    public void setUp(String browser1, String url, int executionMonth) throws Exception {
        exeMonth = executionMonth;
        baseUrl = url;

        if (browser1.equals("FF")) {
            driver = new FirefoxDriver();
        } else if (browser1.equals("IE")){
            driver = new InternetExplorerDriver();
        }       
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);    
    }       

    @Test
    public void R_LHAS_Reports() throws Exception {
        R_LHAS_Only_Login(baseUrl, driver);
        Assert.assertEquals("Kingston upon Thames (RB)", driver.findElement(By.xpath("//html/body/div[9]/div/div[3]/div/div/div")).getText());
        Assert.assertEquals("Average price", driver.findElement(By.xpath("//table[@id='tableId']/tbody/tr/td")).getText());
        Assert.assertEquals("% price change", driver.findElement(By.xpath("//table[@id='tableId']/tbody/tr[2]/td")).getText());
        Assert.assertEquals("Lower quartile price", driver.findElement(By.xpath("//table[@id='tableId']/tbody/tr[3]/td")).getText());
        Assert.assertEquals("Time to sell (weeks)", driver.findElement(By.xpath("//table[@id='tableId']/tbody/tr[4]/td")).getText());
        Assert.assertEquals("% asking price achieved", driver.findElement(By.xpath("//table[@id='tableId']/tbody/tr[5]/td")).getText());
        Assert.assertEquals("House price to earnings ratio", driver.findElement(By.xpath("//table[@id='tableId']/tbody/tr[6]/td")).getText());
        Assert.assertEquals("Cost of buying outright - LQ 2 bed £pw", driver.findElement(By.xpath("//table[@id='tableId']/tbody/tr[7]/td")).getText());
        Assert.assertEquals("Private rent 2 bed £pw", driver.findElement(By.xpath("//table[@id='tableId']/tbody/tr[8]/td")).getText());
        Assert.assertEquals("80% private rent 2 bed £pw", driver.findElement(By.xpath("//table[@id='tableId']/tbody/tr[9]/td")).getText());
        Assert.assertEquals("Social rent 2 bed £pw", driver.findElement(By.xpath("//table[@id='tableId']/tbody/tr[10]/td")).getText());                 
        R_LHAS_Only_Logout(baseUrl,driver);
    }

    @AfterClass(alwaysRun=true)
    public void tearDown() throws Exception {
        driver.quit();
        String verificationErrorString = verificationErrors.toString();
        if (! "".equals(verificationErrorString)) {
            fail(verificationErrorString);
        }
    }   
}
Daniel Serodio
  • 4,229
  • 5
  • 37
  • 33
user929258
  • 405
  • 2
  • 11
  • 16
  • Not a problem at all. When you say highlight an element, do you want to mimic the user holding down the mouse and actually highlighting that element? – AndyPerfect May 18 '12 at 22:35
  • Basically when the tests are running i want to be able to see elements being verified, asserted etc. In simple words I am looking for webdriver equivalent for this: selenium.getEval("selenium.browserbot.setShouldHighlightElement(true)"); This is from selenium RC but i am migrating my test scripts to webdriver. – user929258 May 18 '12 at 22:41

11 Answers11

29

There is no way to do this in WebDriver (as of v2.21.0). You can try replacing the usual findElement(By) method with an adjusted one that uses JavaScript to highlight the found element:

// Draws a red border around the found element. Does not set it back anyhow.
public WebElement findElement(By by) {
    WebElement elem = driver.findElement(by);
    // draw a border around the found element
    if (driver instanceof JavascriptExecutor) {
        ((JavascriptExecutor)driver).executeScript("arguments[0].style.border='3px solid red'", elem);
    }
    return elem;
}

Now that you got the idea, there's an improved version that restores the original border of the last element when a new one is found and highlighted:

// assuming JS is enabled
private JavascriptExecutor js = (JavascriptExecutor)driver;
private WebElement lastElem = null;
private String lastBorder = null;

private static final String SCRIPT_GET_ELEMENT_BORDER;
private static final String SCRIPT_UNHIGHLIGHT_ELEMENT;

void highlightElement(WebElement elem) {
    unhighlightLast();

    // remember the new element
    lastElem = elem;
    lastBorder = (String)(js.executeScript(SCRIPT_GET_ELEMENT_BORDER, elem));
}

void unhighlightLast() {
    if (lastElem != null) {
        try {
            // if there already is a highlighted element, unhighlight it
            js.executeScript(SCRIPT_UNHIGHLIGHT_ELEMENT, lastElem, lastBorder);
        } catch (StaleElementReferenceException ignored) {
            // the page got reloaded, the element isn't there
        } finally {
            // element either restored or wasn't valid, nullify in both cases
            lastElem = null;
        }
    }
}

And the scripts! I load them from a file using FileUtils.readFileToString().

SCRIPT_GET_ELEMENT_BORDER (IE friendly version taken from this site), it would be way shorter if it used highlighting via changing the background color, say, only the bottom border. But this is the nicest one :).

/*
 * Returns all border properties of the specified element as String,
 * in order of "width style color" delimited by ';' (semicolon) in the form of:
 * 
 * "2px inset #000000;2px inset #000000;2px inset #000000;2px inset #000000"
 * "medium none #ccc;medium none #ccc;1px solid #e5e5e5;medium none #ccc"
 * etc.
 */
var elem = arguments[0]; 
if (elem.currentStyle) {
    // Branch for IE 6,7,8. No idea how this works on IE9, but the script
    // should take care of it.
    var style = elem.currentStyle;
    var border = style['borderTopWidth']
            + ' ' + style['borderTopStyle']
            + ' ' + style['borderTopColor']
            + ';' + style['borderRightWidth']
            + ' ' + style['borderRightStyle']
            + ' ' + style['borderRightColor']
            + ';' + style['borderBottomWidth']
            + ' ' + style['borderBottomStyle']
            + ' ' + style['borderBottomColor']
            + ';' + style['borderLeftWidth']
            + ' ' + style['borderLeftStyle']
            + ' ' + style['borderLeftColor'];
} else if (window.getComputedStyle) {
    // Branch for FF, Chrome, Opera
    var style = document.defaultView.getComputedStyle(elem);
    var border = style.getPropertyValue('border-top-width')
            + ' ' + style.getPropertyValue('border-top-style')
            + ' ' + style.getPropertyValue('border-top-color')
            + ';' + style.getPropertyValue('border-right-width')
            + ' ' + style.getPropertyValue('border-right-style')
            + ' ' + style.getPropertyValue('border-right-color')
            + ';' + style.getPropertyValue('border-bottom-width')
            + ' ' + style.getPropertyValue('border-bottom-style')
            + ' ' + style.getPropertyValue('border-bottom-color')
            + ';' + style.getPropertyValue('border-left-width')
            + ' ' + style.getPropertyValue('border-left-style')
            + ' ' + style.getPropertyValue('border-left-color');
}
// highlight the element
elem.style.border = '2px solid red';
return border;

SCRIPT_UNHIGHLIGHT_ELEMENT

var elem = arguments[0];
var borders = arguments[1].split(';');
elem.style.borderTop = borders[0];
elem.style.borderRight = borders[1];
elem.style.borderBottom = borders[2];
elem.style.borderLeft = borders[3];

Any questions, notes, requests and improvements are welcome!

Petr Janeček
  • 37,768
  • 12
  • 121
  • 145
  • @Slance - Thanks for this! Apologies for my ignorance but where would i call the above code in my class? – user929258 May 18 '12 at 23:26
  • Instead of `driver.findElement()`, you can call just `findElement()` now if you add this to your class. Or name it in any other appropriate way :). – Petr Janeček May 18 '12 at 23:28
  • Ok, the method now stores the original border value of the found element and restores it back when a new element is highlighted. I'm hopefully finally done with the edits (as I can't come up with any other improvement) :). – Petr Janeček May 19 '12 at 00:01
  • Thank you Slance - I will give this a go when I am back at work tomorrow - Really appreciate ally your effort of refining of the script :) – user929258 May 20 '12 at 10:51
  • ...written after two weeks or so. I ended up using it, so I tweaked it further and further and it finally became this. It's been stable for a week and no further improvements are planned as of now, so I'm posting it for future readers and for solid use :). – Petr Janeček Jun 07 '12 at 09:47
5

In webdriver
Create a class for highligh element HighlightElement

HighlightElement.java

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;

import com.project.setup.WebDriverManager;

public class HighlightElement {

    public static void highlightElement(WebElement element) {
        for (int i = 0; i <2; i++) {
            JavascriptExecutor js = (JavascriptExecutor) WebDriverManager.driver;
            js.executeScript("arguments[0].setAttribute('style', arguments[1]);", element, "color: yellow; border: 2px solid yellow;");
            js.executeScript("arguments[0].setAttribute('style', arguments[1]);", element, "");
            }
        }
}

You can use

HighlightElement.highlightElement(driver.findElement(By.xpath("blaah blaah"));)

to highlight the WebElement with xpath "blaah blaah" in your test.
  • Thank you for your code example! But I get an error including WebDriverManager via maven3: `[ERROR] /home/leder/Projekt/Selenide/google_test/src/test/java/de/auticon/selenide/google_test/HighlightElement.java:[17,74] cannot find symbol [ERROR] symbol: variable driver [ERROR] location: class io.github.bonigarcia.wdm.WebDriverManager` – Leder Mar 07 '19 at 12:28
3

JavaScript : Find Xpath of an element and Draw Border around it,

using styleObj.setProperty(CSS propertyName, CSS propertyValue, priority) method. element_node.style.setProperty ("background-color", "green", null);

test js-code on this site : https://developer.chrome.com/devtools/docs/console

var xpath = '//html/body/div/main/article/nav';
if (document.evaluate){
var element_node = document.evaluate(xpath, window.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue;
element_node.style.setProperty ('border', '3px solid green', 'important');

alert('Working Fine in this browser version');
}else{
alert('document.evaluate is Not supported by Internet Explorer');
}

Selenium

public static void drawBorder(WebDriver driver, String xpath){
        WebElement element_node = driver.findElement(By.xpath(xpath));
        JavascriptExecutor jse = (JavascriptExecutor) driver;
        jse.executeScript("arguments[0].style.border='3px solid red'", element_node);
    }
Community
  • 1
  • 1
Yash
  • 9,250
  • 2
  • 69
  • 74
1

I use below code for highlighting in my webdriver java code using javascript executer:

//I make a call below function "flash"

    public static void flash(WebElement element, WebDriver driver) {
        JavascriptExecutor js = ((JavascriptExecutor) driver);
        String bgcolor  = element.getCssValue("backgroundColor");
        for (int i = 0; i <  3; i++) {
            changeColor("rgb(0,200,0)", element, js);
            changeColor(bgcolor, element, js);
        }
    }
    public static void changeColor(String color, WebElement element,  JavascriptExecutor js) {
        js.executeScript("arguments[0].style.backgroundColor = '"+color+"'",  element);

        try {
            Thread.sleep(20);
        }  catch (InterruptedException e) {
        }
     }

Hope that helped :)

1

Here the code for higlighting the element in selenium: First create a class:

package com.demo.misc.function;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class Miscellaneous 
{
    public static void highLight(WebElement element, WebDriver driver)
    {
        for (int i = 0; i <2; i++) 
        {
            try {
                JavascriptExecutor js = (JavascriptExecutor) driver;
                js.executeScript("arguments[0].setAttribute('style', arguments[1]);", element, "color: black; border: 4px solid red;");
                Thread.sleep(500);
                js.executeScript("arguments[0].setAttribute('style', arguments[1]);", element, "");
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

}

And then you can call this by :

driver.get(baseUrl);
            Thread.sleep(2000);
            WebElement lnkREGISTER = driver.findElement(By.linkText("REGISTER"));
            Miscellaneous.highLight(lnkREGISTER, driver);
            lnkREGISTER.click();
0

I am unaware of any way to do this in WebDriver, but it looks like there exists a class in Selenium WebDriver that should give you access to most if not all of the RC API. I'm not aware of how to actually do this using WebDriver.

The class WebDriverBackedSelenium looks like it contains much of the RC api you're used to including getEval

To create an object of type WebDriverBackedSelenium, just pass in the driver you've already been using in addition to your testing site's base URL

WebDriverBackedSelenium wdbs = new WebDriverBackedSelenium(driver, "http://www.google.com");
AndyPerfect
  • 1,180
  • 1
  • 10
  • 25
  • Note that this answer is temporary. I'm going to keep looking around to see if this is possible using strictly WebDriver – AndyPerfect May 18 '12 at 22:53
  • Yeah, as of now, there's no such possibility using WebDriver without any JavaScript. However, this might just work as intended. – Petr Janeček May 19 '12 at 00:32
0

This worked for me. Have improved upon the code submitted earlier on this thread.

public static WebDriver HighlightElement(WebDriver driver, WebElement element){ 
    if (driver instanceof JavascriptExecutor) {
        ((JavascriptExecutor)driver).executeScript("arguments[0].style.border='3px solid red'", element);
    }
    return driver;
}
public static WebDriver UnhighlightElement(WebDriver driver, WebElement element){   
    if (driver instanceof JavascriptExecutor) {    
        ((JavascriptExecutor)driver).executeScript("arguments[0].style.border=''", element);
    }
    return driver;  
}

Call these two functions once to highlight and once to unhighlight

André Kool
  • 4,880
  • 12
  • 34
  • 44
0

I am using ExtentReport as a report tool and I am adding images in the failed test steps as a base64 format, which allows me to display them right after the text in the output report. When I am taking screenshots and want to highlight element(s) in order to be more visible in the screenshot I am using the following method to highlight -> screenshot -> un-highlight.

private void highlightElement(WebElement elemToHighlight) {
    if (_driver instanceof JavascriptExecutor) {
        ((JavascriptExecutor) _driver).executeScript("arguments[0].style.border='3px solid red'", elem);
    }
}


public String addScreenshotToHTML(WebElement... elmsToHighlight) {
    String result;
    List<String> initStyle = new ArrayList<>();
    if (elmsToHighlight.length > 0) {
        for (WebElement elem : elmsToHighlight) {
            initStyle.add(elem.getCssValue("border"));
            highlightElement(elem);
        }
    }
    String screenshot = ((TakesScreenshot) _driver).getScreenshotAs(OutputType.BASE64);
    // NOTE: add the <img> tag content between the <a> tags with the Base64 image
    // <a href='" + filePath + "' target='_blank'></a>
    result = "<img onclick='(function(){var image=new Image();image.src=\"data:image/png;base64," + screenshot
            + "\";var w=window.open(\"\");w.document.write(image.outerHTML);})()' style='width:400px; cursor:pointer;' src='data:image/png;base64,"
            + screenshot + "'>";
    if (elmsToHighlight.length > 0) {
        for (WebElement elem : elmsToHighlight) {
            jsExec().executeScript("arguments[0].style.border='" + initStyle.get(0) + "'", elem);
            initStyle.remove(0);
        }
    }
    return result;
}

Hope that helps

0

For highlighting the element you can just use this:

JavascriptExecutor js =(JavascriptExecutor)driver;
js.executeScript("arguments[0].style.border='5px dotted yellow'", element);
Norayr Sargsyan
  • 1,737
  • 1
  • 12
  • 26
  • 1
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Clijsters Jul 01 '20 at 18:44
0

I have Created this method for my testProject in java, First it get the WebElement and then it will check if the element is displayed and if element is displayed, it will highlight that element and then take screenshot and save it.

For source code : How to Highlight element in ScreenShot

public void getValidationMessage(){
    private By errorMessage = By.id("slfErrorAlert");
    WebElement validationMessage = driver.findElement(errorMessage);
    Boolean isElementDisplayed = validationMessage.isDisplayed();
    if (isElementDisplayed){
        JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;
        javascriptExecutor.executeScript("arguments[0].style.border='2px solid red'", validationMessage);
        var getScreenShot = (TakesScreenshot) driver;
        File screenShot = getScreenShot.getScreenshotAs(OutputType.FILE);
        try {
            Files.move(screenShot, new File("src/test/resources/screenShots/validationError.png"));
        } catch (IOException e) {
            e.getStackTrace();
            e.getMessage();
        }
    }
    else{
        System.out.println("Element Not Displayed");
    }
}
Ahtisham Ilyas
  • 365
  • 1
  • 3
  • 15
-1
public class JavaExecutor {

public static void highlighElement(WebDriver driver,WebElement element)
{
    JavascriptExecutor js=(JavascriptExecutor)driver; 
    js.executeScript("arguments[0].setAttribute('style', 'background: yellow; border: 2px solid red;');", element);

    try 
    {
    Thread.sleep(1000);
    } 
    catch (InterruptedException e) {

    System.out.println(e.getMessage());
    } 

    js.executeScript("arguments[0].setAttribute('style','border: solid 2px white');", element); 

    }
}
Amit Pal
  • 177
  • 3
  • 11