Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Как сделать полный скриншот страницы

screenshot
Теги: #<Tag:0x00007f7b650af310>

(babar.igor) #1

Добрый день.
Цель - сделать полноразмерный скриншот страниц писем в Gmail.

*Пример страницы письма:
*

Ожидаемый результат:

Код для снятия скриншота (всей страницы):

public void shoot() throws IOException
{
	File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
	FileUtils.copyFile(screenshot, new File("screen.png"));
}

Фактически полученный скриншот:

Данный метод делает скрин видимой на момент работы теста области браузера, хотя на других сайтах, все работает ок.

Пробовал метод для снятия скриншота указанного веб-элемента по его координатам.

Код для снятия скриншота веб-элемента (по координатам):

public void shoot(WebElement element) throws IOException
{
	driver = new Augmenter().augment(driver);

	File screen = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
	Point p = element.getLocation();
	int width = element.getSize().getWidth();
	int height = element.getSize().getHeight();
	Rectangle rect = new Rectangle(width, height);
	BufferedImage img = ImageIO.read(screen);
	BufferedImage dest = img.getSubimage(p.getX(), p.getY(), rect.width, rect.height);
	ImageIO.write(dest, "png", screen);
	FileUtils.copyFile("screen.png"));
}

Данный метод не может снять скриншот области письма, потому что оно как бы выходит хитрым образом за предел зоны видимости - RasterFormatException: (y + height) is outside of Raster.

На форумах в мире говорят что проблема связана с особенностями верстки страницы, в частности со свойствами overflow и position - на Gmail при скроле страницы, скролится лишь тело письма.

Самостоятельно решить проблему не удалось. Прошу консультаций.

P.S. Вариант с уменьшением масштаба страницы не подходит - важно состояние верстки при масштабе страницы по умолчанию.


Как сделать скриншот всей страницы в python?
(Дмитрий Жарий) #2

Я понимаю, что это хак, но попробуйте растянуть окно браузера в высоту, например на + 2000 пикселей.

На C# это выглядит так:

using System.Collections.Generic;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Drawing.Imaging;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            FirefoxDriver d = new FirefoxDriver();
            d.Manage().Window.Maximize();
            var size = d.Manage().Window.Size;

            size.Height += 2000; // <---- вот тут вот
            d.Manage().Window.Size = size;

            d.Url = "http://automated-testing.info";
            var screenShot = d.GetScreenshot();
            screenShot.SaveAsFile("atinfo.png", ImageFormat.Png);

            d.Quit();
        }
    }
}

а вот результат:


(babar.igor) #3

Не помогло. Высота окна браузера не может быть увеличена на значение, большее чем разрешение экрана по высоте. А развернутое на весь экран окно браузера не решает проблему.

Код:

@Test
public void test()
{
            ...
	Dimension dim = driver.manage().window().getSize();
	System.out.println(dim); // Dimension before: 1928x1044

	driver.manage().window().setSize(new Dimension(dim.width, dim.height + 2000));
	System.out.println(driver.manage().window().getSize()); // Dimension after: 1928x1092
            ...
}

(Дмитрий Жарий) #4

Но, у меня же как-то получилось O_O
А вы используете Firefox драйвер? И WebDriver 2.38?

Есть еще один вариант, который может вам помочь – это использовать специальную библиотеку для “внутреннего” рендеринга. Это не самый стабильный и быстрый вариант, но, можете попробовать.

Код на C#, но там вся фишка в подключении и вызове функции библиотеки html2canvas и есть инструкции и комментарии:

https://gist.github.com/dzhariy/6572995


(Вячеслав Артемчук) #5

Какая версия Вебдрайвера и Хрома?
Извините за питон, но у меня скриншоты снимаются в полный рост без шаманства:

from selenium import webdriver
driver = webdriver.Chrome()

driver.get('http://automated-testing.info/t/kak-sdelat-polnyj-skrinshot-straniczy/3854')
driver.get_screenshot_as_file('/home/at_info.png')

driver.quit()


Как сделать скриншот всей страницы в python?
(babar.igor) #6

Использую FirefoxDriver 2.38)
Понимаете ли, чтобы сделать скриншот полной страницы, которую предоставили Вы, достаточно стандартной процедуры скриншотирования. А Вы попробуйте сделать то же самое, но в письме Gmail. Я описал изначально, что проблема именно там, из-за особенностей верстки.

p.s. Если вы снимите параметры окна браузера при увеличении высоты +2000 в своем примере, я думаю вы увидите, что у вас так же НЕ увеличивается окно браузера, и высота не достигает значения, большего, чем высота разрешения монитора


(babar.igor) #7

То же самое. Попробуйте в Gmail выполнить аналогичное действие при открытом письме) Я писал об этом в условии проблемы.


(Дмитрий Жарий) #8

Да, я сам только что на Gmail попробовал – действительно показывает только видимую часть.
Я заметил, что у письма есть кнопка “во весь экран” справа сверху.

Может быть, попробовать снять скриншот с того окошка?


(babar.igor) #9

Действительно) Попробую. Но, это не решает проблему со снятием скрина именно на исходной странице)


(babar.igor) #10

Попробовал… Учитывая, что нам необходимо будет снимать скриншоты с нескольких сотен писем в различных браузерах для различных почтовых доменов… переключаться между окнами будет трудоемко. Все же, хотелось бы делать скриншот на исходной странице письма. Но, этот вариант оставим.


(barancev) #11

Давайте я объясню, что здесь происходит и почему нельзя достичь желаемого результата (в общем случае). Дело в том, что в приведённом примере (Gmail) мы имеем дело с блоком, имеющим свойство overflow:scroll. То есть скроллируется не страница, а некий блок, находящийся на ней. Ещё таким же свойством обладают вложенные фреймы (iframe), они также могут иметь свой скроллбар.

Так вот – нет никакой гарантии, что изменяя размер страницы вы сможете растянуть эти блоки и фреймы со своими собственными скроллбарами так, чтобы они показывались полностью. Часто они вообще имеют фиксированный размер, поэтому увеличение размера окна вообще никак на них не влияет.

Единственный способ избавиться от скроллбара – изменить размер самого блока или фрейма, то есть поменять вёрстку страницы. Это слишком жёсткое вмешательство, Selenium такого делать не будет. Хотите – пишите сами на JS код, меняющий размер блоков перед снятием скриншотов, под вашу ответственность.