2011-12-27 12 views
5

En Interface TakesScreenshot página que encontré esto:¿Es posible capturar una captura de pantalla para un webelement directamente usando WebDriver?

Captura la pantalla y guardarlo en la ubicación especificada. Para WebDriver extendiéndose TakesScreenshot, esto hace un mayor esfuerzo dependiendo del navegador para regresar el siguiente en el orden de preferencia: - Toda la página - Ventana actual - Porción visible de la trama actual - La captura de pantalla de toda la pantalla que contiene el navegador

para WebElement extendiéndose TakesScreenshot, esto hace un mayor esfuerzo dependiendo del navegador para regresar el siguiente orden de preferencia : - la totalidad del contenido del elemento HTML - el parte visisble del elemento HTML.

Así que me pregunto si debería ser compatible con la captura de pantalla de un webelement, pero no puede encontrar ningún documento relacionado con este soporte en este momento. no estoy seguro de si realmente es compatible o no.

¿Alguien sabe más detalles sobre esto? Gracias.

Respuesta

1

La documentación indicaría que se compatible, pero en la práctica, no funciona (al menos no con los enlaces .Net):

var screenshotTaker = element as ITakesScreenshot; 
var image = screenshotTaker.GetScreenshot(); 
image.SaveAsFile(fileName, ImageFormat.Jpeg); // << null exception thrown here 

Hay una solución que ha funcionado para mí - ejecutar javascript en la página para obtener la ubicación del elemento:

const string javascript = "return arguments[0].getBoundingClientRect()"; 
var obj = (Dictionary<string, object>)((IJavaScriptExecutor)_core.Driver).ExecuteScript(javascript, element); 
var rect = new Rectangle((int)double.Parse(obj["left"].ToString()), 
         (int)double.Parse(obj["top"].ToString()), 
         (int)double.Parse(obj["width"].ToString()), 
         (int)double.Parse(obj["height"].ToString())); 

que le dará la ubicación del elemento dentro de la ventana, en cuyo punto se puede tomar una captura de pantalla de la página entera y recortarla Dow n solo a los límites del elemento.

Esperemos que ayuda ...

+1

¿La clase WebElement en sí misma no tiene métodos para arriba, izquierda, ancho y alto? Parece que el enlace de Java hace: elemento.getLocation(). getX(), element.getSize(). getWidth(), etc. Pero es bueno que proporcione este fragmento de código. Podría ser útil para enlaces de lenguaje que no tienen esa información de forma nativa. – David

1

Siguiendo la idea de @Anders, en Java - no requiere Javascript (usando javaPng):

byte[] imageBytes = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.BYTES); 
BufferedImage img = new PngImage().read(new ByteArrayInputStream(imageBytes), true); 

//set element to the required webElement 
BufferedImage crop = img.getSubimage(element.getLocation().x, 
    element.getLocation().y, element.getSize().width, element.getSize().height); 
+0

A veces me topa con una excepción como "RasterFormatException: (x + ancho) está fuera de Raster" para este tipo de implementación. Pero no sucede todo el tiempo. Solo estoy usando las coordenadas y el tamaño del elemento, así que de ninguna manera eso puede ser incorrecto. Curiosamente, no hay problema con el uso de otras bibliotecas como http://www.javaxt.com/javaxt-core/javaxt.io.Image/ – David

0

probar este

WebDriver driver = new FirefoxDriver(); 
WebElement webElement = driver.findElements(By.xpath("//html")).get(0); 

File screen = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); 
BufferedImage img = ImageIO.read(screen); 

File f = new File('element.png'); 

Point p = webElement.getLocation(); 
int width = webElement.getSize().getWidth(); 
int height = webElement.getSize().getHeight(); 
BufferedImage dest = img.getSubimage(p.getX(), p.getY(), width, height); 
ImageIO.write(dest, "png", f); 

Entonces, después de verificar que esto funciona, reemplace el webElement con su propio elemento. Ejecute este código primero para asegurarse de que su controlador de web tenga la capacidad de captura de pantalla y que su archivo funcione como se espera (es decir, descubrirá dónde se guardan los archivos).

Lo que hace es capturar una captura de pantalla, la guarda en un archivo. Luego, lee ese archivo como una imagen y toma una subimagen basada en la posición del elemento. Luego, guarda esa imagen secundaria en archivo. Esto requiere dos escrituras de archivo y una lectura de archivo (por lo que probablemente haya una buena optimización para esto).

1
public static Bitmap FullScreen { get; set; } 
public static Bitmap Image { get; set; } 

public static void TakeScreenShot(ChromeDriver driver, IWebElement element) 
{ 
    Screenshot screenshot = ((ITakesScreenshot)driver).GetScreenshot(); 

    screenshot.SaveAsFile(Environment.CurrentDirectory + @"\screens\file.bmp", ImageFormat.Bmp); 

    FullScreen = new Bitmap(Environment.CurrentDirectory + @"\screens\file.bmp"); 

    Size element_size = element.Size; 
    Point element_location = element.Location; 

    Rectangle rect = new Rectangle(element_location, element_size); 

    Image = FullScreen.Clone(rect, PixelFormat.Format24bppRgb); 

    Image.Save(Environment.CurrentDirectory + @"\screens\file2.bmp", ImageFormat.Bmp); 

} 

void Main() 
{ 
    ChromeDriver driver = new ChromeDriver(); 

    driver.Navigate().GoToUrl("http://domain.com"); 

    Thread.Sleep(1500); 
    IWebElement _element = driver.findElementById("ElementIdGoesHere"); 
    TakeScreenShot(driver, _element); 
} 

Este código se aproveche captura de pantalla de la página, entonces se buscará la ubicación _element y la imagen se guardará en el disco con el rectángulo del tamaño del elemento.

Cuestiones relacionadas