1

I am trying to write a protractor test to check that a page's footer is at the bottom of the page.

I've looked at sources like these to help me:

How to get an element's top position relative to the browser's viewport? https://plainjs.com/javascript/styles/get-the-position-of-an-element-relative-to-the-document-24/

I want to use the getBoundingClientRect function discussed in these sources to get the footer's position, but I am getting an error saying: footer.getBoundingClientRect is not a function

Here is the relevant portion of my code:

footer = element(by.css('lib-footer > mat-toolbar'));
const viewportOffset = footer.getBoundingClientRect();
const bottom = viewportOffset.bottom;

browser.driver.manage().window().getSize().then((size) => {
    expect(bottom).toBeGreaterThan(size.height - 50);
});

I know that the footer element is defined because I have already run other tests on it to check things like its color and size.

Why am I being told that getBoundingClientRect is not a function?

Daniel C Jacobs
  • 691
  • 8
  • 18

1 Answers1

1

This error occurred because you are trying to call the getBoundingClientRect() function on the ElementFinder type, but the ElementFinder does not have and can not call the getBoundingClientRect function.

The getBoundingClientRect function could be called from the Element object, it is the most general base class from which all objects in a Document inherit. It only has methods and properties common to all kinds of elements. More specific classes inherit from Element.

So in your case, you should use the executeScript to execute JavaScript in the context of the currently selected frame or window.

SOLUTION:

// Promise based

const footer = $('lib-footer > mat-toolbar'); // or element(by.css(''));
let viewportOffset = '';
browser.executeScript('return arguments[0].getBoundingClientRect()', footer).then(value => {
 viewportOffset = value;
});
const bottom = viewportOffset.bottom;

browser.driver.manage().window().getSize().then((size) => {
  expect(bottom).toBeGreaterThan(size.height - 50);
});


// async/await - Highly recommended. Don't forget to add `async` before the function to use `await`


const footer = $('lib-footer > mat-toolbar');
const viewportOffset = await browser.executeScript('return arguments[0].getBoundingClientRect()', footer);
const bottom = viewportOffset.bottom;
const windowSize = await browser.driver.manage().window().getSize();

expect(bottom).toBeGreaterThan(windowSize.height - 50);
Yevhen Laichenkov
  • 7,746
  • 2
  • 27
  • 33
  • This is great!! I'm just wondering. If my window height is 900 and the footer is at the bottom of the window, why is bottom being set to a value of 768? – Daniel C Jacobs Jul 22 '19 at 16:44
  • because the screen resolution and browser window size are not necessarily equal. The display resolution or display modes of a digital television, computer monitor or display device is the number of distinct pixels in each dimension that can be displayed ... "1024 × 768" means the width is 1024 pixels and the height is 768 pixels. While getSize() is returning the actual browser size. Try to maximize the window size `browser.driver.manage().window().maximize();` – Yevhen Laichenkov Jul 22 '19 at 17:41
  • The browser window size is set to 1600 x 900 pixels. The screen resolution is larger than that, so shouldn't 'bottom' be very close to 900 if it's at the very bottom of the browser?. – Daniel C Jacobs Jul 22 '19 at 19:02