WatiN NativeElement.GetElementBounds () - Какая единица измерения? - PullRequest
2 голосов
/ 17 мая 2010

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

Моя попытка сохранить изображение элемента с кодом, приведенным ниже, привела к изображению блока блока, потому что elementBounds.Top указывает на позицию пикселя в нижней части экрана. Значения elementBounds.Width и .Height также примерно вдвое меньше, чем должны быть.

Это ошибка WatiN, или это свойства в другой единице измерения, которые мне нужно каким-то образом преобразовать в пиксели?

public static void SaveElementScreenshot
    (WatiN.Core.IE ie, WatiN.Core.Element element, string screenshotPath)
{
    ScrollIntoView(ie, element);
    ie.BringToFront();

    var ieClass = (InternetExplorerClass) ie.InternetExplorer;

    Rectangle elementBounds = element.NativeElement.GetElementBounds();
    int left = ieClass.Left + elementBounds.Left;
    int top = ieClass.Top + elementBounds.Top;
    int width = elementBounds.Width;
    int height = elementBounds.Height;

    using (var bitmap = new Bitmap(width, height))
    {
        using (Graphics graphics = Graphics.FromImage(bitmap))
        {
            graphics.CopyFromScreen
                (new Point(left, top), Point.Empty, new Size(width, height));
        }

        bitmap.Save(screenshotPath, ImageFormat.Jpeg);
    }
}

1 Ответ

1 голос
/ 31 мая 2010

Похоже, это ошибка WatiN. Как обсуждалось на сайте *1001* для отслеживания проблем WatiN, метод "получить границы" для элементов Internet Explorer выглядит следующим образом:

internal static Rectangle GetHtmlElementBounds(IHTMLElement element)
{
    int offsetLeft = element.offsetLeft;
    int offsetTop = element.offsetTop;
    for (IHTMLElement element2 = element.parentElement; element2 != null; element2 = element2.parentElement)
    {
        offsetLeft += element2.offsetLeft;
        offsetTop += element2.offsetTop;
    }
    int width = element.offsetWidth / 2;
    return new Rectangle(offsetLeft, offsetTop, width, element.offsetHeight / 2);
}

Ошибка в том, что она делит offsetWidth и offsetHeight на 2.

Я заменил вызов element.NativeElement.GetElementBounds, чтобы вызвать мой собственный метод "GetElementBounds", и он работает так, как я хочу:

private static Rectangle GetElementBounds(Element element)
{
    var ieElem = element.NativeElement as WatiN.Core.Native.InternetExplorer.IEElement;
    IHTMLElement elem = ieElem.AsHtmlElement;

    int left = elem.offsetLeft;
    int top = elem.offsetTop;

    for (IHTMLElement parent = elem.offsetParent; parent != null; parent = parent.offsetParent)
    {
        left += parent.offsetLeft;
        top += parent.offsetTop;
    }

    return new Rectangle(left, top, elem.offsetWidth, elem.offsetHeight);
}

Единственная оставшаяся проблема заключается в том, что свойства top и left не компенсируют размер "хрома" окна браузера, поэтому скриншот элемента находится ниже и вправо, чем должно быть.

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

...