【问题标题】:Highlight elements in WebDriver during runtime在运行时突出显示 WebDriver 中的元素
【发布时间】:2012-05-26 11:31:32
【问题描述】:

有人可以帮忙吗!

如何在 WebDriver 中执行测试期间突出显示以下课程中的所有 Web 元素? 使用 Selenium RC,它非常简单,但使用 WebDriver 我正在苦苦挣扎。

如果有人能提供一些我可以尝试的代码,我将不胜感激,以及该代码在哪里适合下面的类 - 抱歉,我的 Java 技能不是那么好。

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);
        }
    }   
}

【问题讨论】:

  • 完全没有问题。当您说突出显示某个元素时,您是否想模仿用户按住鼠标并实际突出显示该元素?
  • 基本上,当测试运行时,我希望能够看到正在验证、断言等的元素。简而言之,我正在寻找与此等效的 webdriver:selenium.getEval("selenium.browserbot.setShouldHighlightElement (真的)”);这是来自 selenium RC,但我正在将我的测试脚本迁移到 webdriver。

标签: java selenium webdriver


【解决方案1】:

为了突出显示元素,你可以使用这个:

JavascriptExecutor js =(JavascriptExecutor)driver;
js.executeScript("arguments[0].style.border='5px dotted yellow'", element);

【讨论】:

  • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
【解决方案2】:

我使用 ExtentReport 作为报告工具,并且我将失败的测试步骤中的图像添加为 base64 格式,这样我就可以在输出报告中的文本之后立即显示它们。当我截取屏幕截图并想要突出显示元素以便在屏幕截图中更明显时,我使用以下方法突出显示 -> 屏幕截图 -> 取消突出显示。

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;
}

希望有帮助

【讨论】:

    【解决方案3】:

    这对我有用。已改进之前在此线程上提交的代码。

    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;  
    }
    

    调用这两个函数一次高亮,一次取消高亮

    【讨论】:

      【解决方案4】:

      这里是在 selenium 中突出显示元素的代码: 首先创建一个类:

      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();
                  }
      
              }
      
          }
      
      }
      

      然后您可以通过以下方式调用它:

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

      【讨论】:

        【解决方案5】:
        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); 
        
            }
        }
        

        【讨论】:

          【解决方案6】:

          JavaScript : 找到element 中的Xpath 并在其周围绘制边框,

          使用 styleObj.setProperty(CSS propertyName, CSS propertyValue, priority) 方法。 element_node.style.setProperty ("background-color", "green", null);

          在本站测试 js 代码: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');
          }
          

          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);
              }
          

          【讨论】:

            【解决方案7】:

            在网络驱动程序中
            为高亮元素 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, "");
                        }
                    }
            }
            

            你可以使用

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

            在您的测试中使用 xpath "blaah blaah" 突出显示 WebElement。

            【讨论】:

            • 感谢您的代码示例!但我收到一个错误,包括通过 maven3 的 WebDriverManager:[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
            【解决方案8】:

            WebDriver(自 v2.21.0 起)中无法执行此操作。您可以尝试将常用的 findElement(By) 方法替换为使用 JavaScript 突出显示找到的元素的调整方法:

            // 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;
            }
            

            现在你已经明白了,有一个改进的版本可以在找到并突出显示新元素时恢复最后一个元素的原始border

            // 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;
                    }
                }
            }
            

            还有脚本!我使用 FileUtils.readFileToString() 从文件中加载它们。

            SCRIPT_GET_ELEMENT_BORDER (IE friendly version taken from this site),如果它通过改变背景颜色来使用高亮显示会更短,比如说,只有底部边框。但这是最好的一个:)。

            /*
             * 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];
            

            欢迎提出任何问题、注释、请求和改进!

            【讨论】:

            • @Slance - 谢谢!为我的无知道歉,但我会在我的课堂上调用上面的代码吗?
            • 如果您将其添加到您的课程中,您现在可以只调用findElement() 而不是driver.findElement()。或以任何其他适当的方式命名它:)。
            • 好的,该方法现在存储找到的元素的原始边框值,并在突出显示新元素时将其恢复。希望我终于完成了编辑(因为我无法提出任何其他改进):)。
            • 谢谢你,Slance - 明天我回来工作时我会试一试 - 非常感谢你为完善脚本所做的努力:)
            • ...两周左右后写的。我最终使用了它,所以我进一步调整它,最终变成了这个。它已经稳定了一周,目前没有进一步的改进计划,所以我将它发布给未来的读者和可靠的使用:)。
            【解决方案9】:

            我使用下面的代码在我的 webdriver java 代码中使用 javascript 执行器突出显示:

            //我在函数“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) {
                    }
                 }
            

            希望有所帮助:)

            【讨论】:

              【解决方案10】:

              我不知道在 WebDriver 中有什么方法可以做到这一点,但看起来 Selenium WebDriver 中存在一个类,它可以让您访问大部分(如果不是全部)RC API。我不知道如何使用 WebDriver 实际执行此操作。

              WebDriverBackedSelenium 类看起来包含了很多你习惯的 RC api,包括 getEval

              要创建WebDriverBackedSelenium 类型的对象,只需传入您已经使用过的驱动程序以及测试站点的基本 URL

              WebDriverBackedSelenium wdbs = new WebDriverBackedSelenium(driver, "http://www.google.com");
              

              【讨论】:

              • 请注意,这个答案是临时的。我将继续环顾四周,看看这是否可以严格使用 WebDriver
              • 是的,到目前为止,在没有任何 JavaScript 的情况下使用 WebDriver 是不可能的。但是,这可能会按预期工作。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2019-08-02
              • 2015-02-11
              • 1970-01-01
              • 2017-11-05
              • 2011-05-16
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多