2011-12-27 5 views
5

A Interface TakesScreenshot pagina ho trovato questo:È possibile acquisire direttamente una schermata per un elemento Web utilizzando WebDriver?

cattura lo screenshot e memorizzarlo nella posizione specificata. Per WebDriver estendentesi TakesScreenshot, questo fa una migliore sforzo seconda del browser per tornare seguente, in ordine di preferenza: - Intera pagina - finestra corrente - porzione visibile della trama attuale - La schermata dell'intero display contenente il del browser

per WebElement estendere TakesScreenshot, questo rende un massimo sforzo a seconda del browser per tornare quanto segue in ordine di preferenza : - l'intero contenuto dell'elemento HTML - il visisble parte dell'elemento HTML.

Quindi mi sto chiedendo dovrebbe supportare lo screenshot di acquisizione di un webelement, ma non riesco a trovare alcun documento si riferiscono a questo supporto ormai. non sono sicuro se sia davvero supportato o meno.

qualcuno conosce più dettagli a riguardo? Grazie.

risposta

1

La documentazione indicherebbe che è supportato, ma in pratica, non funziona (almeno non con le associazioni .Net):

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

c'è una soluzione che ha funzionato per me - eseguire JavaScript nella pagina per ottenere la posizione dell'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())); 

che vi darà la posizione dell'elemento all'interno della finestra, a quel punto si può prendere uno screenshot dell'intera pagina e ritagliarla dow n solo ai limiti dell'elemento.

Speriamo che aiuta ...

+1

La classe WebElement stessa non ha metodi per top, left, width e height? Sembra che l'associazione Java faccia: elemento.getLocation(). getX(), element.getSize(). getWidth(), ecc. Ma è bene che tu fornisca questo snippet di codice. Potrebbe essere utile per i binding della lingua che non hanno queste informazioni in modo nativo. – David

1

Seguendo l'idea di @Anders, in Java - javascript richiesto (utilizzando 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 volte eseguo eccezioni come "RasterFormatException: (x + width) è all'esterno di Raster" per questo tipo di implementazione. Ma non succede tutto il tempo. Sto solo usando le coordinate e le dimensioni dell'elemento, quindi nessun modo può essere sbagliato. È interessante notare che nessun problema utilizza altre librerie come http://www.javaxt.com/javaxt-core/javaxt.io.Image/ – David

0

Prova questa

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

Poi, dopo aver verificato che funzioni, sostituire webElement con il proprio elemento. Esegui questo codice prima solo per assicurarti che il tuo webdriver abbia la capacità di screen shot e che il tuo file funzioni come previsto (ovvero scoprirai dove sono salvati i file).

Ciò che fa è catturare uno screenshot, salvarlo in un file. Quindi, legge quel file come un'immagine e acquisisce un'immagine secondaria basata sulla posizione dell'elemento. Quindi salva l'immagine secondaria nel file. Ciò richiede due scritture di file e un file letto (quindi ci sarebbe probabilmente una buona ottimizzazione per questo).

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

Questo codice potrai screenshot della pagina, quindi cercherà la posizione _element e l'immagine verrà salvata sul disco utilizzando la dimensione rettangolare dell'elemento.

Problemi correlati