Highlight elements in WebDriver during runtime

后端 未结 10 1189
离开以前
离开以前 2020-12-02 15:54

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

相关标签:
10条回答
  • 2020-12-02 16:42

    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!

    0 讨论(0)
  • 2020-12-02 16:43

    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 讨论(0)
  • 2020-12-02 16:45

    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);
        }
    
    0 讨论(0)
  • 2020-12-02 16:47
    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); 
    
        }
    }
    
    0 讨论(0)
提交回复
热议问题