2012-12-12 84 views
48

現在、私はSelenium WebDriverを使用してスクリーンショットをキャプチャしようとしています。しかし、私は全体のページのスクリーンショットを取得することができます。しかし、私が望んでいたのは、ページの一部をキャプチャするか、IDまたは特定の要素ロケータに基づいて特定の要素にキャプチャすることです。 (例えば、画像ID = "Butterfly"の画像をキャプチャしたい)Selenium Webdriverを使用して、ページ全体ではなく特定の要素のスクリーンショットをキャプチャする方法は?

選択した項目や要素でスクリーンショットをキャプチャする方法はありますか?

+1

私の知る限り、施設は全体をキャプチャすることですページ。要素IDまたは名前を入力として受け取るスクリーンショット関数はありません。 – Hemanth

+0

誰かが、C#でBUFFeredImageのメソッド呼び出しを教えてくれますか?私はこれに関連する類似の方法を見つけることができませんでした。 – fj123

答えて

69

私たちは以下のようにページ全体のスクリーンショットをトリミングすることによって要素のスクリーンショットを取得することができます:

driver.get("http://www.google.com"); 
WebElement ele = driver.findElement(By.id("hplogo")); 

// Get entire page screenshot 
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); 
BufferedImage fullImg = ImageIO.read(screenshot); 

// Get the location of element on the page 
Point point = ele.getLocation(); 

// Get width and height of the element 
int eleWidth = ele.getSize().getWidth(); 
int eleHeight = ele.getSize().getHeight(); 

// Crop the entire page screenshot to get only element screenshot 
BufferedImage eleScreenshot= fullImg.getSubimage(point.getX(), point.getY(), 
    eleWidth, eleHeight); 
ImageIO.write(eleScreenshot, "png", screenshot); 

// Copy the element screenshot to disk 
File screenshotLocation = new File("C:\\images\\GoogleLogo_screenshot.png"); 
FileUtils.copyFile(screenshot, screenshotLocation); 
+0

ありがとうございます。しかし、なぜ私のwebdriverがあなたと違うのですか?それはIWebDriver、ITakeScreenshotを使用し、OutputType.FILEとBufferedImageはありません... webdriverセレンの古いバージョンを使用していますか? – fj123

+0

C#webdriverバインディングを使用していますか? – Surya

+0

はい、そうだと思います。以前はRCを使用していましたが、最近はWebドライバを使用するように変更しています。 – fj123

4

私は、スクリーンショットを撮るには多くの時間を無駄にし、私はあなたを保存したいです。 私はクロム+セレン+ Cを使用して#結果は完全に恐ろしいです。最終的に私は機能書いた:WD.jsと非常にコンパクトなイメージライブラリはEasyImageと呼ばれる:Node.js

driver.Manage().Window.Maximize(); 
      RemoteWebElement remElement = (RemoteWebElement)driver.FindElement(By.Id("submit-button")); 
      Point location = remElement.LocationOnScreenOnceScrolledIntoView; 

      int viewportWidth = Convert.ToInt32(((IJavaScriptExecutor)driver).ExecuteScript("return document.documentElement.clientWidth")); 
      int viewportHeight = Convert.ToInt32(((IJavaScriptExecutor)driver).ExecuteScript("return document.documentElement.clientHeight")); 

      driver.SwitchTo(); 

      int elementLocation_X = location.X; 
      int elementLocation_Y = location.Y; 

      IWebElement img = driver.FindElement(By.Id("submit-button")); 

      int elementSize_Width = img.Size.Width; 
      int elementSize_Height = img.Size.Height; 

      Size s = new Size(); 
      s.Width = driver.Manage().Window.Size.Width; 
      s.Height = driver.Manage().Window.Size.Height; 

      Bitmap bitmap = new Bitmap(s.Width, s.Height); 
      Graphics graphics = Graphics.FromImage(bitmap as Image); 
      graphics.CopyFromScreen(0, 0, 0, 0, s); 

      bitmap.Save(filePath, System.Drawing.Imaging.ImageFormat.Png); 

      RectangleF part = new RectangleF(elementLocation_X, elementLocation_Y + (s.Height - viewportHeight), elementSize_Width, elementSize_Height); 

      Bitmap bmpobj = (Bitmap)Image.FromFile(filePath); 
      Bitmap bn = bmpobj.Clone(part, bmpobj.PixelFormat); 
      bn.Save(finalPictureFilePath, System.Drawing.Imaging.ImageFormat.Png); 
+0

スクロールせずに表示されている要素をキャプチャしようとしても、正常に機能します。キャプチャする要素にスクロールする必要がある場合、yオフセットはページの上部から計算され、フルスクリーンイメージの境界を超えます。したがって、最も簡単な解決策は、スクリーンサイズコードthis.driver.manage()。window()を増やすことです。setSize(new Dimension(1680、1050));またはCSS以外の要素を削除することができます。適切な解決策は、スクロールからyオフセットを計算することです。 – Ichwardort

9

を、私は動作しますが、それはセレンの公式WebDriverJSに基づいていますが、SauceLabs's WebDriverに基づいていない、次のコードを書きました。

私はただ要素のスクリーンショットを撮ることはできませんが、最初にページ全体のスクリーンショットを撮ってから、好きな部分を選択してその特定の部分を切り抜くことを強調したいと思います。

browser.get(URL_TO_VISIT) 
     .waitForElementById(dependentElementId, webdriver.asserters.isDisplayed, 3000) 
     .elementById(elementID) 
     .getSize().then(function(size) { 
      browser.elementById(elementID) 
        .getLocation().then(function(location) { 
         browser.takeScreenshot().then(function(data) { 
          var base64Data = data.replace(/^data:image\/png;base64,/, ""); 
          fs.writeFile(filePath, base64Data, 'base64', function(err) { 
           if (err) { 
            console.log(err); 
           } 
           else { 
            cropInFile(size, location, filePath); 
           } 
           doneCallback(); 
         }); 
        }); 
       }); 
      }); 

そしてcropInFileFunctionは、このように書きます:あなたは、ディスクIOを伴う気にしない場合

var cropInFile = function(size, location, srcFile) { 
    easyimg.crop({ 
      src: srcFile, 
      dst: srcFile, 
      cropwidth: size.width, 
      cropheight: size.height, 
      x: location.x, 
      y: location.y, 
      gravity: 'North-West' 
     }, 
     function(err, stdout, stderr) { 
      if (err) throw err; 
     }); 
}; 
2

Surya's answerは素晴らしい作品。あなたは、このメソッドは良いかもしれむしろたくない場合のために、あなた

private Image getScreenshot(final WebDriver d, final WebElement e) throws IOException { 
    final BufferedImage img; 
    final Point topleft; 
    final Point bottomright; 

    final byte[] screengrab; 
    screengrab = ((TakesScreenshot) d).getScreenshotAs(OutputType.BYTES); 

    img = ImageIO.read(new ByteArrayInputStream(screengrab)); 

    //crop the image to focus on e 
    //get dimensions (crop points) 
    topleft = e.getLocation(); 
    bottomright = new Point(e.getSize().getWidth(), 
          e.getSize().getHeight()); 

    return img.getSubimage(topleft.getX(), 
          topleft.getY(), 
          bottomright.getX(), 
          bottomright.getY()); 
} 

あなたがscreengrabを宣言し、代わりにクリーナーです

img = ImageIO.read(
    new ByteArrayInputStream(
     ((TakesScreenshot) d).getScreenshotAs(OutputType.BYTES))); 

をやってスキップすることができます好むが、私はそれを左の場合明快さ。あなたの心のコンテンツにsave it as a fileまたはput it in a JPanelをつけることができます。

8

YandexのからASHOTフレームワークは、このフレームワークはhttps://github.com/yandex-qatools/ashot上で見つけることができ

    のためのセレンwebdriverをスクリプトで
  • フルWebページ
  • ウェブ要素

をスクリーンショットを撮るために使用することができます。

スクリーンショットを取るためのコードは非常に簡単です:

ページ全体

screenshot = new AShot().shootingStrategy(
new ViewportPastingStrategy(1000)).takeScreenshot(driver); 
ImageIO.write(screenshot.getImage(), "PNG", new File("c:\\temp\\results.png")); 

特定のWeb ELEMENT

screenshot = new AShot().takeScreenshot(driver, 
driver.findElement(By.xpath("(//div[@id='ct_search'])[1]"))); 

ImageIO.write(screenshot.getImage(), "PNG", new File("c:\\temp\\div_element.png")); 

this articleの詳細と多くのコードサンプルを参照してください。

+0

'Specifying WEB ELEMENT'モードでも '.shootingStrategy(ShootingStrategies.viewportPast(100))'が必要な場合や、すべての要素を取得しない場合があるので注意してください。 – user1686407

2
public void GenerateSnapshot(string url, string selector, string filePath) 
    { 
     using (IWebDriver driver = new ChromeDriver()) 
     { 
      driver.Navigate().GoToUrl(url); 
      var remElement = driver.FindElement(By.CssSelector(selector)); 
      Point location = remElement.Location; 

      var screenshot = (driver as ChromeDriver).GetScreenshot(); 
      using (MemoryStream stream = new MemoryStream(screenshot.AsByteArray)) 
      { 
       using (Bitmap bitmap = new Bitmap(stream)) 
       { 
        RectangleF part = new RectangleF(location.X, location.Y, remElement.Size.Width, remElement.Size.Height); 
        using (Bitmap bn = bitmap.Clone(part, bitmap.PixelFormat)) 
        { 
         bn.Save(filePath, System.Drawing.Imaging.ImageFormat.Png); 
        } 
       } 
      } 
      driver.Close(); 
     } 
    } 
4

C#でコードを要求するすべての人のために、以下は私の実装の簡略化されたバージョンです。

public static void TakeScreenshot(IWebDriver driver, IWebElement element) 
{ 
    try 
    { 
     string fileName = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".jpg"; 
     Byte[] byteArray = ((ITakesScreenshot)driver).GetScreenshot().AsByteArray; 
     System.Drawing.Bitmap screenshot = new System.Drawing.Bitmap(new System.IO.MemoryStream(byteArray)); 
     System.Drawing.Rectangle croppedImage = new System.Drawing.Rectangle(element.Location.X, element.Location.Y, element.Size.Width, element.Size.Height); 
     screenshot = screenshot.Clone(croppedImage, screenshot.PixelFormat); 
     screenshot.Save(String.Format(@"C:\SeleniumScreenshots\" + fileName, System.Drawing.Imaging.ImageFormat.Jpeg)); 
    } 
    catch (Exception e) 
    { 
     logger.Error(e.StackTrace + ' ' + e.Message); 
    } 
} 
+0

ありがとうございます。それは非常に有用で、ポイントまで完璧でした。 –

-2

私は@ブルックの回答の修正版を使用していさえスクロールするページを必要とする要素のために正常に動作しています。スクロールが必要とされたときに、作物のサイズは、1つのピクセルのスクリーンショットのサイズが超過しているため

public void TakeScreenshot(string fileNameWithoutExtension, IWebElement element) 
{ 
    // Scroll to the element if necessary 
    var actions = new Actions(_driver); 
    actions.MoveToElement(element); 
    actions.Perform(); 
    // Get the element position (scroll-aware) 
    var locationWhenScrolled = ((RemoteWebElement) element).LocationOnScreenOnceScrolledIntoView; 
    var fileName = fileNameWithoutExtension + ".png"; 
    var byteArray = ((ITakesScreenshot) _driver).GetScreenshot().AsByteArray; 
    using (var screenshot = new System.Drawing.Bitmap(new System.IO.MemoryStream(byteArray))) 
    { 
     var location = locationWhenScrolled; 
     // Fix location if necessary to avoid OutOfMemory Exception 
     if (location.X + element.Size.Width > screenshot.Width) 
     { 
      location.X = screenshot.Width - element.Size.Width; 
     } 
     if (location.Y + element.Size.Height > screenshot.Height) 
     { 
      location.Y = screenshot.Height - element.Size.Height; 
     } 
     // Crop the screenshot 
     var croppedImage = new System.Drawing.Rectangle(location.X, location.Y, element.Size.Width, element.Size.Height); 
     using (var clone = screenshot.Clone(croppedImage, screenshot.PixelFormat)) 
     { 
      clone.Save(fileName, ImageFormat.Png); 
     } 
    } 
} 

2つのif sが(少なくともクロムドライバ用)が必要でした。

+0

私はあなたのメソッドを試してみるとこのエラーが出ます: 'OpenQA.Selenium.Remote.RemoteWebElement'と入力して透明なプロキシをキャストすることができません – shanabus

+0

私はこのドライバをChrome Driver専用に使用します。 – thepirat000

+0

私はChromeDriverも使用しています。私のテストはIWebElementsを使用しており、私たちはOpenQA.Selenium.Support nugetパッケージのPageFactoryメソッドに従っています。 – shanabus

0
using System.Drawing; 
using System.Drawing.Imaging; 
using OpenQA.Selenium; 
using OpenQA.Selenium.Firefox; 

public void ScreenshotByElement() 
{ 
    IWebDriver driver = new FirefoxDriver(); 
    String baseURL = "www.google.com/"; //url link 
    String filePath = @"c:\\img1.png";  

    driver.Navigate().GoToUrl(baseURL); 
    var remElement = driver.FindElement(By.Id("Butterfly")); 
    Point location = remElement.Location; 

    var screenshot = (driver as FirefoxDriver).GetScreenshot(); 
    using (MemoryStream stream = new MemoryStream(screenshot.AsByteArray)) 
    { 
     using (Bitmap bitmap = new Bitmap(stream)) 
     { 
      RectangleF part = new RectangleF(location.X, location.Y, remElement.Size.Width, remElement.Size.Height); 
      using (Bitmap bn = bitmap.Clone(part, bitmap.PixelFormat)) 
      { 
       bn.Save(filePath, ImageFormat.Png);       
      } 
     } 
    } 
} 
-1

C#を使用しているので、私のソリューションにはJavaライブラリが含まれていますが、他の人には役立つかもしれません。

カスタムスクリーンショットをキャプチャするには、Shutterbugライブラリを使用できます。この目的のために特定の呼び出しは次のようになります。

Shutterbug.shootElement(driver, element).save(); 
1

は針使用を検討してください - 組み込まれている(CSSのセレクタで選択された)特定の要素のスクリーンショットを取ることを可能にする機能が自動化された視覚的に比較 https://github.com/bfirsh/needle、 ためのツールを。このツールはSeleniumのWebDriverで動作し、Pythonで書かれています。

0

以下は、Seleniumの特定の要素をスナップショットとして取得する機能です。ここでドライバはWebDriverの一種です。

private static void getScreenshot(final WebElement e, String fileName) throws IOException { 
    final BufferedImage img; 
    final Point topleft; 
    final Point bottomright; 
    final byte[] screengrab; 
    screengrab = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES); 
    img = ImageIO.read(new ByteArrayInputStream(screengrab)); 
    topleft = e.getLocation(); 
    bottomright = new Point(e.getSize().getWidth(), e.getSize().getHeight()); 
    BufferedImage imgScreenshot= 
     (BufferedImage)img.getSubimage(topleft.getX(), topleft.getY(), bottomright.getX(), bottomright.getY()); 
    File screenshotLocation = new File("Images/"+fileName +".png");  
    ImageIO.write(imgScreenshot, "png", screenshotLocation); 
} 
+0

**詳細については、このリンクを参照してください。** [Automation Hub Point](http://automationhubpoint.blogspot.in/2017/01/how-to-capture-screenshot-of-specific.html) –

1

あなたがJavaScriptのソリューションを探しているなら、ここに私の要点です:

https://gist.github.com/sillicon/4abcd9079a7d29cbb53ebee547b55fba

基本的な考え方は同じで、それをトリミング、最初のスクリーンショットを取ります。 しかし、私のソリューションでは純粋なWebDriver APIコードだけで他のライブラリは必要ありません。しかし、副作用はテストブラウザの負荷を増加させる可能性があることです。ここで

1

は、C#の拡張機能である:

public static BitmapImage GetElementImage(this IWebDriver webDriver, By by) 
{ 
    var elements = webDriver.FindElements(by); 
    if (elements.Count == 0) 
     return null; 

    var element = elements[0]; 
    var screenShot = (webDriver as ITakesScreenshot).GetScreenshot(); 
    using (var ms = new MemoryStream(screenShot.AsByteArray)) 
    { 
     Bitmap screenBitmap; 
     screenBitmap = new Bitmap(ms); 
     return screenBitmap.Clone(
      new Rectangle(
       element.Location.X, 
       element.Location.Y, 
       element.Size.Width, 
       element.Size.Height 
      ), 
      screenBitmap.PixelFormat 
     ).ToBitmapImage(); 
    } 
} 

今、あなたは、このような任意の要素の画像を撮るためにそれを使用することができます:

var image = webDriver.GetElementImage(By.Id("someId")); 
関連する問題