Как захватить снимок экрана определенного элемента, а не всей страницы, используя Selenium Webdriver?
В настоящее время я пытаюсь захватить скриншот, используя Selenium WebDriver. Но я могу получить только весь экранный снимок экрана. Однако я хотел просто захватить часть страницы или, возможно, только конкретный элемент на основе идентификатора или какого-либо определенного локатора элементов. (Например, я хочу захватить изображение с изображением id = «Butterfly»)
Есть ли способ захватить скриншот выбранного элемента или элемента?
- Как сделать снимок экрана и поделиться им программно
- андроид, снимок экрана с экрана
- Можете ли вы снять «скриншот» на странице с помощью Canvas?
- Сделайте снимок экрана SurfaceView
- Как предотвратить захват экрана в Android
- Как сделать снимок экрана в OpenGL
- Android получает снимок экрана всех элементов ListView
- Как записывать экран и делать скриншоты с помощью Android API?
- Сделайте снимок экрана в полноэкранном приложении DirectX
- Как сделать снимок экрана текущей веб-страницы с помощью javascript / jquery
- Захват снимка экрана с использованием .NET
- Получить скриншот конкретного приложения
- Программный скрининг на мобильном устройстве
Мы можем получить скриншот элемента, обрезая весь скриншот страницы, как показано ниже:
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);
В Node.js
я написал следующий код, который работает, но не основан на официальном WebDriverJS selenium, но основан на SauceLabs's WebDriver
: WD.js и очень компактной библиотеке изображений под названием EasyImage .
Я просто хочу подчеркнуть, что вы действительно не можете сделать снимок экрана, но то, что вы должны сделать, это сначала сделать скриншот всей страницы, затем выбрать часть страницы, которая вам нравится, и обрезать эту конкретную часть:
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, выглядит следующим образом:
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; }); };
Структура ASHOT из Yandex может использоваться для скриншотов в сценариях Selenium WebDriver для
- полные веб-страницы
- веб-элементы
Эту структуру можно найти на странице https://github.com/yandex-qatools/ashot .
Код для снятия скриншотов очень прост:
ВСЕ СТРАНИЦА
screenshot = new AShot().shootingStrategy( new ViewportPastingStrategy(1000)).takeScreenshot(driver); ImageIO.write(screenshot.getImage(), "PNG", new File("c:\\temp\\results.png"));
КОНКРЕТНЫЙ ВЕБ-ЭЛЕМЕНТ
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"));
См. Более подробную информацию и дополнительные примеры кода в этой статье .
Я потратил много времени на снятие снимков экрана, и я хочу сохранить ваши. Я использовал хром + selenium + c #, результат был абсолютно ужасен. Наконец, я написал функцию:
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);
Для всех, кто запрашивает код на 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); } }
Ответ Сурьи отлично работает, если вы не возражаете против использования диска IO. Если вы не хотите, то этот метод может быть лучше для вас
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)));
который чище, но я оставил его для ясности. Затем вы можете сохранить его в виде файла или поместить его в JPanel в контент вашего сердца.
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(); } }
Рассмотрите возможность использования игольного инструмента для автоматического визуального сравнения https://github.com/bfirsh/needle , который имеет встроенные функции, позволяющие снимать скриншоты определенных элементов (выбранных селектором CSS). Инструмент работает на WebDriver Selenium, и он написан на Python.
Ниже приведена функция для моментального снимка определенного элемента в 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); }
Если вы ищете решение для JavaScript, вот моя суть:
https://gist.github.com/sillicon/4abcd9079a7d29cbb53ebee547b55fba
Основная идея такая же, сначала сделайте снимок экрана, затем обрезайте его. Однако для моего решения не потребуются другие библиотеки, просто чистый код API WebDriver. Однако побочным эффектом является то, что он может увеличить нагрузку вашего браузера тестирования.
Вот функция расширения для 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"));
Вот версия Python 3 с использованием Selenium webdriver и Pillow. Эта программа захватывает скриншот всей страницы и обрезает элемент на основе его местоположения. Изображение элемента будет доступно как image.png
from selenium import webdriver from PIL import Image driver = webdriver.Chrome() driver.get('https://www.google.co.in') element = driver.find_element_by_id("lst-ib") location = element.location size = element.size driver.save_screenshot("shot.png") x = location['x'] y = location['y'] w = size['width'] h = size['height'] width = x + w height = y + h im = Image.open('shot.png') im = im.crop((int(x), int(y), int(width), int(height))) im.save('image.png')
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); } } } }
Я считаю, что это не сработает для вас, так как вы используете C #, и мое решение включает в себя библиотеку Java, однако, возможно, другие сочтут это полезным.
Для захвата пользовательских скриншотов вы можете использовать библиотеку Shutterbug. Конкретным призывом для этой цели было бы следующее:
Shutterbug.shootElement(driver, element).save();
Я использую измененную версию ответа @ Brook и отлично работает даже для элементов, которым нужна прокрутка страницы.
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); } } }
Эти два, if
были необходимы (по крайней мере для драйвера хрома), потому что размер урожая превышал в 1 пиксель размер скриншота, когда требуется прокрутка.