Подсветка искомого элемента, скриншоты

Ребята - задался таким вопросом - хочу делать в процессе тестов скриншоты с подсветкой искомого элемента, знаю что я не первый кто о таком задумался - если у кого-то есть идеи или даже реализации - делитесь кусочками кода.

Ребята из яндекса сделали библиотеку (ссылка на гитхаб)

Она умеет делать такую вещь(на главной проекта на гитхабе даже есть описание, как весь скрин немного размыть)
Сам не пользовался, но коллеги вроде у себя используют.
В крайнем случае - не понравится - можете посмотреть, как они делают фильтры и реализовать самостоятельно

Я уже подключил эту либу но не понял как и куда оно сохраняет скриншот и как его приатачить например к алюр репорту?

Снова таки, я не работаю с html, но как начальную точку для реализации взял бы (по скольку скриншот нужно делать для елемента который отсутствует, то работать буду с родительским)

  1. Вариант взятия скриншота только той области, где должен быть элемент parent_html_element.getBoundingClientRect(); и скриншот по этим кординатам
  2. Вариант CSS Outline, когда мы просто нарисуем яркий толстый красный бордер вокруг родительского элемента и сделаем скриншот всей области страницы.

Ashot.takeScreenshot(…) возвращает Вам объект класса Screenshot. У него есть метод getImage(), который возвращает BufferedImage.

Если вы хотите в аллюр запихать его, можно сделать например вот так:

@Attachment(value = "Снимок ''{0}''", type = "image/png")
public static byte[] saveScreenShot(Screenshot screenshot) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(screenshot.getImage(), "png", baos);
        return baos.toByteArray();
}

Ну а если вы хотите в файл сохранять - тут можно найти на просторах интернета много примеров, как BufferedImage в файл запихать.
При этом кстати вариант снятия скриншота отдельного элемента тоже имеет право на жизнь.

у меня aShot плюс свой метод которий умеет красним прямоугольником елайнить область интеракции (клика, итд итп) - писал на джаве.
виглядит вот так:

private static BufferedImage takeElementScreenshot(WebDriver driver,
		WebElement element, String screenShotStepFilter) {
	BufferedImage elementScreenShotOnStep = null;

	if (screenShotStepFilter.equals("blur")) {
		elementScreenShotOnStep = blurElementOnScreenShot(driver, element);
	} else if (screenShotStepFilter.equals("redline")) {
		BufferedImage pageScreenShot = takeBrowserScreenshot(driver);
		elementScreenShotOnStep = cropElementOnScreenShotWithRectangle(
				pageScreenShot, element);
	} else {
		throw new RuntimeException(
				"Invalid parameter for screenshot filter is set");
	}
	return elementScreenShotOnStep;

}

если screenShotStepFilter - blur - то используеться aShot, если redline - то свой метод , которий обводит красним прямоугольником. Ету пропертю я сетаю глобально как системную для проекта, что б не заморачиваться с конфигами. У меня проперти перед запуском все поднимаються spring-ом с конфиг файла через PropertyPlaceholderConfigurer.

Как я написал метод , которий обводит прямоугольником:

private static BufferedImage cropElementOnScreenShotWithRectangle(
		BufferedImage pageScreenShot, WebElement element) {
	Point point = element.getLocation();
	int eleWidth = element.getSize().getWidth();
	int eleHeight = element.getSize().getHeight();

	// setting the aligned rectangle parameters
	Graphics2D graph = pageScreenShot.createGraphics();
	graph.setColor(Color.RED);
	graph.setStroke(new BasicStroke(3));

	int xRedRectangleMove = 15;
	int yRedRectangleMove = 15;

	if (point.getX() < 15
			|| (pageScreenShot.getWidth() - point.getX()) < 15) {
		xRedRectangleMove = 10;
	}

	if (point.getY() < 15
			|| (pageScreenShot.getHeight() - point.getY()) < 15) {
		yRedRectangleMove = 10;
	}

	graph.drawRect(point.getX() - xRedRectangleMove, point.getY()
			- yRedRectangleMove, eleWidth + xRedRectangleMove * 2,
			eleHeight + yRedRectangleMove * 2);
	graph.dispose();

	// if it would be out of bound it will be cut properly
	BufferedImage elementScreenshot = pageScreenShot.getSubimage(
			point.getX() - 60, point.getY() - 60, eleWidth + 120,
			eleHeight + 120);

	return elementScreenshot;
}

я делаю отступ от координат елемента, так как если у вас например белий input field - то ви на скриншоте нифига не увидите.

Далее как я делаю blur ефект aShot-ом. Я постил баг им на git-е что такой метод не работает в FF.
Вот решение:

Оно не работает (вернее у них на гите не правильний пример через то что ViewportPastingStrategy uses jQuery) , если у сайта нет подключенного jQuery - никакого скриншота не будет))

ну сам метод:

private static BufferedImage blurElementOnScreenShot(WebDriver driver,
			WebElement element) {
		Screenshot imageScreen = new AShot()
				.coordsProvider(new WebDriverCoordsProvider())
				.imageCropper(new IndentCropper() // overwriting cropper
						.addIndentFilter(new BlurFilter()))
				.takeScreenshot(driver, element); // adding filter for indent

		return imageScreen.getImage();
	}

И то и другие возвращает BufferedImage - которий теперь можно перевести в byte array и заатачить скажем в Allure репорту что я делаю успешно.

Насчет подсветить элемент есть статья Алексея Баранцева “Selenium 2.0: замедляем тесты и подсвечиваем элементы”

1 лайк

Вот подстветка елементов на Питоне:

def highlight(element):
    """Highlights (blinks) an element"""
    def apply_style(style):
        driver.execute_script("arguments[0].setAttribute('style', arguments[1]);", element, style)
    original_style = element.get_attribute('style')
    apply_style("background: yellow; border: 2px solid red;")
    time.sleep(.1)
    apply_style(original_style)